using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;

namespace HomeCare
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // TabPatient is the default tab
            // init TabPatient control values
            clearControls_TabPatient();

            // change TabPatient mode
            changeMode_TabPatient(true);

            // retrieve data from database
            refreshData_TabPatient(true, true, true, true, true, true, true);

            m_firstLoad = false;
        }

        #region AllTabs
        void xtraTabControl1_SelectedPageChanged(object sender, DevExpress.XtraTab.TabPageChangedEventArgs e)
        {
            if (e.Page == xtraTabPatients)
            {
                // the first load is done in Form1()
                if (m_firstLoad)
                {
                    // init TabPatient control values
                    clearControls_TabPatient();

                    // change TabPatient mode
                    changeMode_TabPatient(true);

                    // refresh data
                    refreshData_TabPatient(true, true, true, true, true, true, true);

                    m_firstLoad = false;
                }
                else
                {
                    // refresh data
                    refreshData_TabPatient(false, true, true, true, false, false, false);
                }
            }
            else if (e.Page == xtraTabStaff)
            {
                if (m_firstLoad_TabStaff)
                {
                    // init TabStaff control values
                    clearControls_TabStaff();

                    // change TabStaff mode
                    changeMode_TabStaff(true);

                    // refresh data
                    refreshData_TabStaff(true, false, false, true);

                    m_firstLoad_TabStaff = false;
                }
                else
                {
                    // refresh data
                    refreshData_TabStaff(true, false, false, false);
                }
            }
            else if (e.Page == xtraTabServices)
            {
                if (m_firstLoad_TabServices)
                {
                    // init TabServices control values
                    clearControls_TabServices();

                    // change TabServices mode
                    changeMode_TabServices(true);

                    // refresh data
                    refreshData_TabServices(true);

                    m_firstLoad_TabServices = false;
                }
            }
            else if (e.Page == xtraTabCompanies)
            {
                if (m_firstLoad_TabCompanies)
                {
                    // init TabCompanies control values
                    clearControls_TabCompanies();

                    // change TabCompanies mode
                    changeMode_TabCompanies(true);

                    // refresh data
                    refreshData_TabCompanies(true);

                    m_firstLoad_TabCompanies = false;
                }
            }
            else if (e.Page == xtraTabInvoice)
            {
                if (m_firstLoad_TabInvoice)
                {
                    // init TabInvoice control values
                    clearControls_TabInvoice();

                    // change TabInvoice mode
                    changeMode_TabInvoice(true);

                    // refresh data
                    refreshData_TabInvoice(true, true, true, true);

                    m_firstLoad_TabInvoice = false;
                }
                else
                {
                    refreshData_TabInvoice(true, true, true, true);
                }
            }
            else if (e.Page == xtraTabReports)
            {
                if (m_firstLoad_TabReports)
                {
                    // init TabReports control values
                    clearControls_TabReports();

                    // refresh data
                    refreshData_TabReports(true, true, true, true, true);

                    m_firstLoad_TabReports = false;
                }
                else
                {
                    // refresh data
                    refreshData_TabReports(true, true, true, true, true);
                }
            }
        }

        // cancel LookUpEdit Popup when edit
        private void LookUpEditCancelPopUp(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }

        // set LookUpEdit text
        private void setLookUpEditText(LookUpEdit lookUpEdit, String text)
        {
            lookUpEdit.QueryPopUp += new CancelEventHandler(LookUpEditCancelPopUp);
            lookUpEdit.Text = text;
            lookUpEdit.QueryPopUp -= new CancelEventHandler(LookUpEditCancelPopUp);
        }

        private void clearLookUpEdit(LookUpEdit lookUpEdit)
        {
            lookUpEdit.EditValue = null;
        }

        private void resetValidationProvider(DevExpress.XtraEditors.DXErrorProvider.DXValidationProvider provider)
        {
            IList<Control> invalidControls = provider.GetInvalidControls();
            while(invalidControls.Count > 0)
            {
                provider.RemoveControlError(invalidControls[0]);
            }
        }
        #endregion

        #region TabPatient
        #region EventHandlers
        private void BTN_New_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabPatient();

            // change mode
            changeMode_TabPatient(false);
        }

        private void BTN_Cancel_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabPatient();

            // change mode
            changeMode_TabPatient(true);
        }

        private void BTN_Submit_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider1.Validate())
            {
                showMsg_TabPatient(false, "Patient Info Incomplete!");
                return;
            }

            // fill in patient object
            Model.Patient patient   = new Model.Patient();
            patient.LastName        = TE_LastName.Text;
            patient.FirstName       = TE_FirstName.Text;
            patient.Birth           = DE_Birth.DateTime;
            patient.IdentityNo      = TE_ID.Text;
            patient.CompanyID       = Int32.Parse(LU_Company.EditValue.ToString());
            patient.AddressLine1    = TE_Address1.Text;
            patient.AddressLine2    = TE_Address2.Text;
            patient.ZipCode         = TE_ZipCode.Text;
            patient.HomePhone       = TE_HomePhone.Text;
            patient.CellPhone       = TE_CellPhone.Text;
            patient.EmerContName    = TE_EmerName.Text;
            patient.EmerContRelation = TE_EmerRel.Text;
            patient.EmerContNumber  = TE_EmerNumber.Text;
            patient.CaseMgrName     = TE_CaseMgrName.Text;
            patient.CaseMgrTel      = TE_CaseMgrPhone.Text;
            patient.Referer         = LU_Referer.Text;
            patient.RefererPhone    = TE_RefererPhone.Text;
            patient.Diagnosis       = ME_Diagnosis.Text;
            patient.Remark          = ME_Remark.Text;
            patient.EntryDate       = DE_Entry.DateTime;
            patient.Sex             = LU_Sex.Text;
            patient.Enable          = true;

            // set non-Not Null DateTime
            if (String.IsNullOrEmpty(DE_File.Text))
            {
                patient.DateOnFile = null;
            }
            else
            {
                patient.DateOnFile = DE_File.DateTime;
            }

            // write to database
            int newID = s_PatientMgr.Add(patient);
            if (newID > 0)
            {
                // show result
                showMsg_TabPatient(true, "Add Patient Succeed!");

                // clear controls
                clearControls_TabPatient();

                // change mode
                changeMode_TabPatient(true);

                // refresh patient list and referer list
                refreshData_TabPatient(true, false, false, false, true, false, false);

                // show newly add patient
                LU_FullName.EditValue = newID;
            }
            else
            {
                // show result
                showMsg_TabPatient(false, "Add Patient Failed!");
            }
        }

        private void BTN_Update_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider2.Validate())
            {
                showMsg_TabPatient(false, "Patient Info Incomplete!");
                return;
            }

            if (m_currentPatient != null && m_currentPatient.id > 0)
            {
                // check new name
                String firstName    = "";
                String lastName     = "";
                String[] name       = TE_FirstName.Text.Split(new char[] { ',' });
                if (name.Length == 2)
                {
                    lastName = name[0];
                    firstName = name[1];
                }
                else if (name.Length == 1)
                {
                    lastName = name[0];
                    firstName = "";
                }
                else
                {
                    showMsg_TabPatient(false, "Invalid name!");
                    return;
                }

                // fill in current patient
                m_currentPatient.LastName       = lastName;
                m_currentPatient.FirstName      = firstName;
                m_currentPatient.Birth          = DE_Birth.DateTime;
                m_currentPatient.IdentityNo     = TE_ID.Text;
                m_currentPatient.CompanyID      = Int32.Parse(LU_Company.EditValue.ToString());
                m_currentPatient.AddressLine1   = TE_Address1.Text;
                m_currentPatient.AddressLine2   = TE_Address2.Text;
                m_currentPatient.ZipCode        = TE_ZipCode.Text;
                m_currentPatient.HomePhone      = TE_HomePhone.Text;
                m_currentPatient.CellPhone      = TE_CellPhone.Text;
                m_currentPatient.EmerContName   = TE_EmerName.Text;
                m_currentPatient.EmerContRelation = TE_EmerRel.Text;
                m_currentPatient.EmerContNumber = TE_EmerNumber.Text;
                m_currentPatient.CaseMgrName    = TE_CaseMgrName.Text;
                m_currentPatient.CaseMgrTel     = TE_CaseMgrPhone.Text;
                m_currentPatient.Referer        = LU_Referer.Text;
                m_currentPatient.RefererPhone   = TE_RefererPhone.Text;
                m_currentPatient.Diagnosis      = ME_Diagnosis.Text;
                m_currentPatient.Remark         = ME_Remark.Text;
                //m_currentPatient.EntryDate      = DE_Entry.DateTime;
                m_currentPatient.Sex            = LU_Sex.Text;
                m_currentPatient.Enable         = true;

                // set non-Not Null DateTime
                if (String.IsNullOrEmpty(DE_File.Text))
                {
                    m_currentPatient.DateOnFile = null;
                }
                else
                {
                    m_currentPatient.DateOnFile = DE_File.DateTime;
                }

                // set LU_Referer.EditValue to the correct value, such that after 
                // refreshData(), the LU_Referer still points to the correct item
                String referer      = m_currentPatient.Referer;
                String refererPhone = m_currentPatient.Referer + "::" + m_currentPatient.RefererPhone;
                object[] array      = { referer, refererPhone };
                m_RefererList.Tables[0].Rows.Add(array);
                LU_Referer.EditValue = refererPhone;
                
                // update into database
                s_PatientMgr.Update(m_currentPatient);

                // show result
                showMsg_TabPatient(true, "Update Patient Info Succeed!");

                // refresh referer list
                refreshData_TabPatient(true, false, false, false, true, false, false);
            }
        }

        private void BTN_Delete_Click(object sender, EventArgs e)
        {
            if (m_currentPatient != null && m_currentPatient.id > 0)
            {
                if (MessageBox.Show("Delete this Patient?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    // delete this patient and its related invoices and auth records
                    deletePatient(m_currentPatient);

                    // show result
                    showMsg_TabPatient(true, "Patient has been deleted!");

                    // clear controls
                    clearControls_TabPatient();

                    // refresh referer list
                    refreshData_TabPatient(true, false, false, false, true, false, false);
                }
            }
        }

        private void BTN_Clear_Click(object sender, EventArgs e)
        {
            clearLookUpEdit(LU_ServiceType);
            clearLookUpEdit(LU_Staff);

            DE_Auth.Text        = "";
            TE_AuthCode.Text    = "";
            DE_From.Text        = "";
            DE_To.Text          = "";
            TE_Frequency.Text   = "";
            TE_Remark.Text      = "";
        }

        private void BTN_DelAuth_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView1.GetFocusedRow();
            if (row != null && m_currentPatient != null && 
                row["PatientID"].Equals(m_currentPatient.id))
            {
                // ask for delete
                if (MessageBox.Show("Delete this Authorization?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
                {
                    // delete
                    s_AuthRecordMgr.Delete(Int32.Parse(row["id"].ToString()));

                    // refresh
                    refreshData_TabPatient(false, false, false, false, false, true, false);

                    // go to the last auth record
                    gridView1.MoveLast();
                }
            }
        }

        private void BTN_NewAuth_Click(object sender, EventArgs e)
        {
            // check validity
            if (m_currentPatient == null)
            {
                showMsg_TabPatient(false, "No Patient Selected!");
                return;
            }
            else if (!dxValidationProvider3.Validate())
            {
                showMsg_TabPatient(false, "Authorization Info Incomplete!");
                return;
            }

            // fill a record
            Model.AuthorizationRecord record = new Model.AuthorizationRecord();
            record.PatientID    = m_currentPatient.id;
            record.Date         = DE_Auth.DateTime;
            record.Code         = TE_AuthCode.Text;
            record.ServiceStart = DE_From.DateTime;
            record.ServiceEnd   = DE_To.DateTime;
            record.ServiceID    = Int32.Parse(LU_ServiceType.EditValue.ToString());
            record.Frequency    = TE_Frequency.Text;
            record.StaffID      = Int32.Parse(LU_Staff.EditValue.ToString());
            record.Remark       = TE_Remark.Text;

            // write to database
            int newID = s_AuthRecordMgr.Add(record);
            if (newID > 0)
            {
                // show result
                showMsg_TabPatient(true, "Add Authorization Succeed!");

                // refresh
                refreshData_TabPatient(false, false, false, false, false, true, false);

                // go to the last auth record
                gridView1.MoveLast();
            }
            else
            {
                // show result
                showMsg_TabPatient(false, "Add Authorization Failed!");
            }
        }

        private void BTN_UpdateAuth_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView1.GetFocusedRow();
            if (row != null && m_currentPatient != null &&
                row["PatientID"].Equals(m_currentPatient.id))
            {
                if (!dxValidationProvider3.Validate())
                {
                    showMsg_TabPatient(false, "Authorization Info Incomplete!");
                    return;
                }

                // fill a record
                Model.AuthorizationRecord record = new Model.AuthorizationRecord();
                record.id           = Int32.Parse(row["id"].ToString());
                record.PatientID    = m_currentPatient.id;
                record.Date         = DE_Auth.DateTime;
                record.Code         = TE_AuthCode.Text;
                record.ServiceStart = DE_From.DateTime;
                record.ServiceEnd   = DE_To.DateTime;
                //record.ServiceID    = Int32.Parse(LU_ServiceType.EditValue.ToString());
                record.ServiceID    = m_currentAuthView.ServiceID;
                record.Frequency    = TE_Frequency.Text;
                //record.StaffID      = Int32.Parse(LU_Staff.EditValue.ToString());
                record.StaffID      = m_currentAuthView.StaffID;
                record.Remark       = TE_Remark.Text;

                // this is added to resolve the strange change of 
                // staff and type when updating authorization data 
                // without changing the staff and type 
                if (m_serviceTypeChanged)
                {
                    record.ServiceID    = Int32.Parse(LU_ServiceType.EditValue.ToString());
                }
                m_serviceTypeChanged = false;

                if (m_staffChanged)
                {
                    record.StaffID      = Int32.Parse(LU_Staff.EditValue.ToString());
                }
                m_staffChanged = false;

                // write to database
                s_AuthRecordMgr.Update(record);

                // show result
                showMsg_TabPatient(true, "Update Authorization Info Succeed!");

                // save the current position
                int focusRow = gridView1.FocusedRowHandle;

                // refresh
                refreshData_TabPatient(false, false, false, false, false, true, false);

                // set the current position
                gridView1.FocusedRowHandle = focusRow;
            }
            else
            {
                // show result
                showMsg_TabPatient(false, "No Authorization Selected!");
            }
        }

        private void BTN_SamePhone_Click(object sender, EventArgs e)
        {
            List<Model.Patient> allPatients = s_PatientMgr.GetModelList("Enable = 1");
            
            Hashtable samePhone = new Hashtable();
            for (int i = 0; i < allPatients.Count; i++)
            {
                if (!String.IsNullOrEmpty(allPatients[i].HomePhone))
                {
                    String homePhone = allPatients[i].HomePhone;

                    List<Model.Patient> patientList = (List<Model.Patient>)samePhone[homePhone];
                    if (patientList == null) {
                        patientList = new List<HomeCare.Model.Patient>();
                        samePhone.Add(homePhone, patientList);
                    }
                    patientList.Add(allPatients[i]);
                }
            }

            showMsg_TabPatient(true, "Generating Report...");
            if (showSamePhoneReport(samePhone))
            {
                showMsg_TabPatient(true, "Report Generated!");
            }
            else
            {
                showMsg_TabPatient(false, "No Patient with the Same Phone Number!");
            }
        }

        private void BTN_CheckHomePhone_Click(object sender, EventArgs e)
        {
            // clear output first
            showMsg_TabPatient(true, "");

            // get same phone
            String phoneNo = TE_HomePhone.Text;
            if (!String.IsNullOrEmpty(phoneNo))
            {
                List<Model.Patient> patients = s_PatientMgr.GetModelList("Enable=1 AND HomePhone='" + phoneNo + "'");
                
                // delete current patient from list
                for (int i = 0; i < patients.Count && m_currentPatient != null; i++)
                {
                    if (m_currentPatient.id == patients[i].id)
                    {
                        patients.RemoveAt(i);
                        i--;
                    }
                }

                if (patients.Count > 0)
                {
                    String nameList = "";
                    for (int i = 0; i < patients.Count; i++)
                    {
                        nameList += patients[i].LastName + ", " + patients[i].FirstName;
                        if (i != patients.Count - 1)
                        {
                            nameList += "; ";
                        }
                    }
                    showMsg_TabPatient(true, "Patients with the Same Home Phone Number: " + nameList);
                }
                else
                {
                    showMsg_TabPatient(false, "No Patient with the Same Home Phone Number!");
                }
                
            }
        }

        private void BTN_CheckCellPhone_Click(object sender, EventArgs e)
        {
            // clear output first
            showMsg_TabPatient(true, "");

            // get same phone
            String phoneNo = TE_CellPhone.Text;
            if (!String.IsNullOrEmpty(phoneNo))
            {
                List<Model.Patient> patients = s_PatientMgr.GetModelList("Enable=1 AND CellPhone='" + phoneNo + "'");
                
                // delete current patient from list
                for (int i = 0; i < patients.Count && m_currentPatient != null; i++)
                {
                    if (m_currentPatient.id == patients[i].id)
                    {
                        patients.RemoveAt(i);
                        i--;
                    }
                }

                if (patients.Count > 0)
                {
                    String nameList = "";
                    for (int i = 0; i < patients.Count; i++)
                    {
                        nameList += patients[i].LastName + ", " + patients[i].FirstName;
                        if (i != patients.Count - 1)
                        {
                            nameList += "; ";
                        }
                    }
                    showMsg_TabPatient(true, "Patients with the Same Cell Phone Number: " + nameList);
                }
                else
                {
                    showMsg_TabPatient(false, "No Patient with the Same Cell Phone Number!");
                }

            }
        }

        private void LU_FullName_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_FullName.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_FullName.EditValue.ToString());
                    m_currentPatient = s_PatientMgr.GetModel(id);
                    if (m_currentPatient != null)
                    {
                        TE_FirstName.Text       = m_currentPatient.LastName + "," + m_currentPatient.FirstName;
                        DE_Birth.DateTime       = m_currentPatient.Birth;
                        TE_ID.Text              = m_currentPatient.IdentityNo;
                        TE_Address1.Text        = m_currentPatient.AddressLine1;
                        TE_Address2.Text        = m_currentPatient.AddressLine2;
                        TE_ZipCode.Text         = m_currentPatient.ZipCode;
                        TE_HomePhone.Text       = m_currentPatient.HomePhone;
                        TE_CellPhone.Text       = m_currentPatient.CellPhone;
                        TE_EmerName.Text        = m_currentPatient.EmerContName;
                        TE_EmerRel.Text         = m_currentPatient.EmerContRelation;
                        TE_EmerNumber.Text      = m_currentPatient.EmerContNumber;
                        TE_CaseMgrName.Text     = m_currentPatient.CaseMgrName;
                        TE_CaseMgrPhone.Text    = m_currentPatient.CaseMgrTel;
                        ME_Diagnosis.Text       = m_currentPatient.Diagnosis;
                        ME_Remark.Text          = m_currentPatient.Remark;
                        DE_Entry.DateTime       = m_currentPatient.EntryDate;
                        setLookUpEditText(LU_Referer, m_currentPatient.Referer);
                        setLookUpEditText(LU_Sex, m_currentPatient.Sex);

                        // must be placed after LU_Referer is set
                        TE_RefererPhone.Text    = m_currentPatient.RefererPhone;

                        // set non-Not Null DateTime
                        if (m_currentPatient.DateOnFile != null)
                        {
                            DE_File.DateTime = (DateTime)m_currentPatient.DateOnFile;
                        }
                        else
                        {
                            DE_File.Text = "";
                        }

                        // get company name
                        Model.Company company = s_CompanyMgr.GetModel(m_currentPatient.CompanyID);
                        if (company != null)
                        {
                            setLookUpEditText(LU_Company, company.CompanyStr);
                        }

                        // get auth records
                        refreshData_TabPatient(false, false, false, false, false, true, false);

                        // go to the last auth record
                        gridView1.MoveLast();
                    }
                }
                catch (System.Exception /*ex*/)
                {
                	// if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }
            }
        }

        // necessary, otherwise we cannot add a new value
        private void LU_Referer_ProcessNewValue(object sender, ProcessNewValueEventArgs e)
        {
            if (m_RefererList != null)
            {
                String referer      = e.DisplayValue.ToString();
                String refererPhone = referer + "::" + TE_RefererPhone.Text;;
                object[] array      = { referer, refererPhone };
                m_RefererList.Tables[0].Rows.Add(array);
                LU_Referer.EditValue = refererPhone;
            }
        }

        private void LU_Referer_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_Referer.EditValue != null)
            {
                String refererPhone = LU_Referer.EditValue.ToString();
                int index           = refererPhone.IndexOf("::");
                if (index >= 0)
                {
                    refererPhone    = refererPhone.Substring(index + 2);
                    TE_RefererPhone.Text = refererPhone;
                }
            }
        }

        private void LU_ServiceType_EditValueChanged(object sender, EventArgs e)
        {
            clearLookUpEdit(LU_Staff);

            refreshData_TabPatient(false, false, false, true, false, false, false);

            // this is added to resolve the strange change of 
            // staff and type when updating authorization data 
            // without changing the staff and type 
            m_serviceTypeChanged = true;
        }

        // this is added to resolve the strange change of 
        // staff and type when updating authorization data 
        // without changing the staff and type 
        private void LU_Staff_EditValueChanged(object sender, EventArgs e)
        {
            m_staffChanged = true;
        }

        private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DataRowView row = (DataRowView)gridView1.GetFocusedRow();
            if (row != null && m_currentPatient != null &&
                row["PatientID"].Equals(m_currentPatient.id))
            {
                // show current auth record
                m_currentAuthView = 
                    s_AuthRecordViewMgr.GetModel(Int32.Parse(row["id"].ToString()));
                if (m_currentAuthView != null)
                {
                    DE_Auth.DateTime    = m_currentAuthView.Date;
                    DE_From.DateTime    = m_currentAuthView.ServiceStart;
                    DE_To.DateTime      = m_currentAuthView.ServiceEnd;
                    TE_AuthCode.Text    = m_currentAuthView.Code;
                    TE_Frequency.Text   = m_currentAuthView.Frequency;
                    TE_Remark.Text      = m_currentAuthView.Remark;

                    setLookUpEditText(LU_ServiceType, m_currentAuthView.Service);
                    setLookUpEditText(LU_Staff, m_currentAuthView.Name);

                    // this is added to resolve the strange change of 
                    // staff and type when updating authorization data 
                    // without changing the staff and type 
                    m_serviceTypeChanged    = false;
                    m_staffChanged          = false;
                }
            }
        }

        private void gridView1_DoubleClick(object sender, EventArgs e)
        {
            if (gridView1.FocusedColumn != null && 
                gridView1.FocusedColumn.Caption.Equals("Staff"))
            {
                DataRowView row                 = (DataRowView)gridView1.GetFocusedRow();
                String serviceType              = row["Service"].ToString();
                String staffName                = row["Name"].ToString();
                xtraTabControl1.SelectedTabPage = xtraTabStaff;
                setLookUpEditText(LU_ServiceType_TabStaff, serviceType);
                setLookUpEditText(LU_Staff_TabStaff, staffName);
            }
        }
        #endregion

        #region Functions
        private bool showSamePhoneReport(Hashtable samePhone) 
        {
            String strWhere = "";
            IEnumerator values = samePhone.Values.GetEnumerator();
            while (values.MoveNext())
            {
                List<Model.Patient> patientList = (List<Model.Patient>)values.Current;
                if (patientList.Count > 1)
                {
                    for (int j = 0; j < patientList.Count; j++)
                    {
                        if (strWhere.Length > 0)
                        {
                            strWhere += " OR ";
                        }
                        strWhere += "PatientID=" + patientList[j].id;
                    }
                }
            }

            // show report only if there are such cases
            if (strWhere.Length > 0)
            {
                strWhere += " ORDER BY HomePhone, PatientID";

                // create dataset
                DataSet ds = s_ReportViewMgr.GetList2(strWhere);

                // output ds
                // create report
                XRFullReport report = new XRFullReport(ds);
                report.ShowPreview();

                return true;
            }
            else
            {
                return false;
            }
        }


        // refresh data from database
        private void refreshData_TabPatient(bool bPatientList,
                                            bool bCompanyList,
                                            bool bServiceList,
                                            bool bStaffList,
                                            bool bRefererList,
                                            bool bAuthRecordList, 
                                            bool bStaticLists)
        {
            // refresh patient list
            if (bPatientList)
            {
                m_PatientList = s_PatientMgr.GetNames("Enable=1");

                // bind patient names
                if (m_PatientList != null)
                {
                    // bind DataSource
                    LU_FullName.Properties.DataSource       = m_PatientList.Tables[0];
                    LU_FullName.Properties.DisplayMember    = "LastName";
                    LU_FullName.Properties.ValueMember      = "id";
                }
            }

            // refresh company list
            if (bCompanyList)
            {
                //s_CompanyList = s_CompanyMgr.GetList("Enable=1");
                m_CompanyList = s_CompanyMgr.GetList("");

                // bind company names
                if (m_CompanyList != null)
                {
                    // bind DataSource
                    LU_Company.Properties.DataSource    = m_CompanyList.Tables[0];
                    LU_Company.Properties.DisplayMember = "Company";
                    LU_Company.Properties.ValueMember   = "id";
                }
            }

            // refresh service list
            if (bServiceList)
            {
                m_ServceList = s_ServiceMgr.GetList("Enable=1");

                // bind service names
                if (m_ServceList != null)
                {
                    // bind DataSource
                    LU_ServiceType.Properties.DataSource    = m_ServceList.Tables[0];
                    LU_ServiceType.Properties.DisplayMember = "Service";
                    LU_ServiceType.Properties.ValueMember   = "id";
                }
            }

            // refresh staff list
            if (bStaffList && LU_ServiceType.EditValue != null)
            {
                // get staff list
                String sid = LU_ServiceType.EditValue.ToString();
                if (!String.IsNullOrEmpty(sid))
                {
                    m_StaffList = s_StaffMgr.GetList("ServiceID=" + sid + " AND Enable=1 ORDER BY Name");
                }
                else
                {
                    m_StaffList = s_StaffMgr.GetList("Enable=1 ORDER BY Name");
                }

                // bind staff names
                if (m_StaffList != null)
                {
                    // bind DataSource
                    LU_Staff.Properties.DataSource      = m_StaffList.Tables[0];
                    LU_Staff.Properties.DisplayMember   = "Name";
                    LU_Staff.Properties.ValueMember     = "id";
                }
            }

            // refresh referer list
            if (bRefererList)
            {
                m_RefererList = s_PatientMgr.GetReferers("");

                // bind referer names
                if (m_RefererList != null)
                {
                    // bind DataSource
                    LU_Referer.Properties.DataSource    = m_RefererList.Tables[0];
                    LU_Referer.Properties.DisplayMember = "Referer";
                    LU_Referer.Properties.ValueMember   = "RefererPhone";
                }
            }

            // refresh authorization record list
            if (bAuthRecordList)
            {
                if (m_currentPatient != null)
                {
                    // set datasource
                    DataSet ds = s_AuthRecordViewMgr.GetList("PatientID=" + m_currentPatient.id.ToString());
                    GC_AuthRecords.DataSource = ds.Tables[0];
                }
            }

            if (bStaticLists)
            {
                // Sex
                DataTable dtSex = new DataTable();
                dtSex.Columns.Add("Sex");
                dtSex.Rows.Add("Female");
                dtSex.Rows.Add("Male");
                LU_Sex.Properties.DataSource    = dtSex;
                LU_Sex.Properties.DisplayMember = "Sex";
                LU_Sex.Properties.ValueMember   = "Sex";
            }
        }

        private void clearControls_TabPatient()
        {
            // lookup edits
            clearLookUpEdit(LU_FullName);
            clearLookUpEdit(LU_Company);
            clearLookUpEdit(LU_Referer);
            clearLookUpEdit(LU_ServiceType);
            clearLookUpEdit(LU_Staff);
            clearLookUpEdit(LU_Sex);

            // textboxes
            TE_LastName.Text        = "";
            TE_FirstName.Text       = "";
            DE_Birth.Text           = "";
            TE_ID.Text              = "";
            TE_Address1.Text        = "";
            TE_Address2.Text        = "";
            TE_ZipCode.Text         = "";
            TE_HomePhone.Text       = "";
            TE_CellPhone.Text       = "";
            TE_EmerName.Text        = "";
            TE_EmerRel.Text         = "";
            TE_EmerNumber.Text      = "";
            TE_CaseMgrName.Text     = "";
            TE_CaseMgrPhone.Text    = "";
            TE_RefererPhone.Text    = "";
            ME_Diagnosis.Text       = "";
            ME_Remark.Text          = "";
            DE_Entry.DateTime       = DateTime.Now;
            DE_File.Text            = "";

            // auth controls
            DE_Auth.Text            = "";
            TE_AuthCode.Text        = "";
            DE_From.Text            = "";
            DE_To.Text              = "";
            TE_Frequency.Text       = "";
            TE_Remark.Text          = "";
            GC_AuthRecords.DataSource = null;
        }

        private void changeMode_TabPatient(bool bQueryMode)
        {
            if (bQueryMode)
            {
                // set buttons
                BTN_New.Visible         = true;
                BTN_Update.Enabled      = true;
                BTN_Submit.Visible      = false;
                BTN_Cancel.Visible      = false;

                BTN_Clear.Enabled       = true;
                BTN_NewAuth.Enabled     = true;
                BTN_UpdateAuth.Enabled  = true;
                BTN_DelAuth.Enabled     = true;

                 // set input editors
                LU_FullName.Visible     = true;
                TE_LastName.Visible     = false;

                // use full name for query
                LB_LastName.Text        = "Full Name: ";
                LB_FirstName.Text       = "Full Name: ";

                // reset validation provider
                resetValidationProvider(dxValidationProvider1);

                // set focus
                LU_FullName.Focus();
            }
            else
            {
                // set buttons
                BTN_New.Visible         = false;
                BTN_Update.Enabled      = false;
                BTN_Submit.Visible      = true;
                BTN_Cancel.Visible      = true;

                BTN_Clear.Enabled       = false;
                BTN_NewAuth.Enabled     = false;
                BTN_UpdateAuth.Enabled  = false;
                BTN_DelAuth.Enabled     = false;

                 // set input editors
                LU_FullName.Visible     = false;
                TE_LastName.Visible     = true;

                // input last name and first name separately
                LB_LastName.Text        = "Last Name: ";
                LB_FirstName.Text       = "First Name: ";

                // set focus
                TE_LastName.Focus();
            }
        }

        private void deletePatient(Model.Patient patientToDelete)
        {
            patientToDelete.Enable = false;
            s_PatientMgr.Update(patientToDelete);

            // delete invoices related to this Patient
            List<Model.Invoice> invoices = s_InvoiceMgr.GetModelList("PatientID=" + patientToDelete.id);
            for (int i = 0; i < invoices.Count; i++)
            {
                deleteInvoice(invoices[i]);
            }

            // delete auths related to this Patient
            List<Model.AuthorizationRecord> authRecords = s_AuthRecordMgr.GetModelList("PatientID=" + patientToDelete.id);
            for (int i = 0; i < authRecords.Count; i++)
            {
                s_AuthRecordMgr.Delete(authRecords[i].id);
            }
        }

        private void showMsg_TabPatient(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success.ForeColor = Color.Green;
            }
            else
            {
                LB_Success.ForeColor = Color.Red;
            }

            LB_Success.Text = msg;
            LB_Success.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success.Size.Width / 2),
                                            LB_Success.Location.Y);
        }
        #endregion

        #region Members
        private bool m_firstLoad                = true;
        private Model.Patient m_currentPatient  = null;
        private DataSet m_PatientList           = null;
        private DataSet m_CompanyList           = null;
        private DataSet m_ServceList            = null;
        private DataSet m_StaffList             = null;
        private DataSet m_RefererList           = null;
        private Model.AuthorizationRecordView m_currentAuthView = null;
        // this is added to resolve the strange change of 
        // staff and type when updating authorization data 
        // without changing the staff and type 
        private bool m_serviceTypeChanged       = false;
        private bool m_staffChanged             = false;
        #endregion
        #endregion

        #region TabStaff
        #region EventHandlers
        private void BTN_New_TabStaff_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabStaff();

            // change mode
            changeMode_TabStaff(false);
        }

        private void BTN_Cancel_TabStaff_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabStaff();

            // change mode
            changeMode_TabStaff(true);
        }

        private void BTN_Submit_TabStaff_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider4.Validate())
            {
                showMsg_TabStaff(false, "Staff Info Incomplete!");
                return;
            }

            // fill in staff object
            Model.Staff staff   = new Model.Staff();
            staff.Name          = TE_Staff_TabStaff.Text;
            staff.ServiceID     = Int32.Parse(LU_ServiceType_TabStaff.EditValue.ToString());
            staff.Enable        = true;
            staff.IdentityNo    = TE_ID_TabStaff.Text;
            staff.Sex           = LU_Sex_TabStaff.EditValue.ToString();
            staff.Language      = LU_Language_TabStaff.EditValue.ToString();
            staff.Drive         = LU_Drive_TabStaff.EditValue.ToString().Equals("Yes");
            staff.Waiting       = LU_Waiting_TabStaff.EditValue.ToString().Equals("Yes");
            staff.Allowance     = TE_Allowance_TabStaff.Text;
            staff.StartWorkDate = DE_StartDate_TabStaff.DateTime;
            staff.EndWorkDate   = DE_EndDate_TabStaff.DateTime;
            staff.AddressLine1  = TE_Address1_TabStaff.Text;
            staff.AddressLine2  = TE_Address2_TabStaff.Text;
            staff.ZipCode       = TE_ZipCode_TabStaff.Text;
            staff.HomePhone     = TE_HomePhone_TabStaff.Text;
            staff.CellPhone     = TE_CellPhone_TabStaff.Text;
            staff.Fax           = TE_Fax_TabStaff.Text;
            staff.Email         = TE_Email_TabStaff.Text;
            staff.Remark        = ME_Remark_TabStaff.Text;
            staff.SSN           = TE_SSN_TabStaff.Text;

            // set non-Not Null DateTime
            if (String.IsNullOrEmpty(DE_Birth_TabStaff.Text))
            {
                staff.Birth = null;
            }
            else
            {
                staff.Birth = DE_Birth_TabStaff.DateTime;
            }

            // write to database
            int newID = s_StaffMgr.Add(staff);
            if (newID > 0)
            {
                // show result
                showMsg_TabStaff(true, "Add Staff Succeed!");

                // clear controls
                clearControls_TabStaff();

                // change mode
                changeMode_TabStaff(true);

                // refresh staff list
                refreshData_TabStaff(false, true, false, false);

                // show newly add staff
                LU_ServiceType_TabStaff.EditValue   = staff.ServiceID;
                LU_Staff_TabStaff.EditValue         = newID;
            }
            else
            {
                // show result
                showMsg_TabStaff(false, "Add Staff Failed!");
            }
        }

        private void BTN_Update_TabStaff_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider5.Validate())
            {
                showMsg_TabStaff(false, "Staff Info Incomplete!");
                return;
            }

            if (m_currentStaff != null && m_currentStaff.id > 0)
            {
                // fill in current staff
                m_currentStaff.Name         = TE_Staff2_TabStaff.Text;
                m_currentStaff.ServiceID    = Int32.Parse(LU_ServiceType_TabStaff.EditValue.ToString());
                m_currentStaff.Enable       = true;
                m_currentStaff.Sex          = LU_Sex_TabStaff.EditValue.ToString();
                m_currentStaff.Language     = LU_Language_TabStaff.EditValue.ToString();
                m_currentStaff.Drive        = LU_Drive_TabStaff.EditValue.ToString().Equals("Yes");
                m_currentStaff.Waiting      = LU_Waiting_TabStaff.EditValue.ToString().Equals("Yes");
                m_currentStaff.Allowance    = TE_Allowance_TabStaff.Text;
                m_currentStaff.StartWorkDate = DE_StartDate_TabStaff.DateTime;
                m_currentStaff.EndWorkDate  = DE_EndDate_TabStaff.DateTime;
                m_currentStaff.IdentityNo   = TE_ID_TabStaff.Text;
                m_currentStaff.AddressLine1 = TE_Address1_TabStaff.Text;
                m_currentStaff.AddressLine2 = TE_Address2_TabStaff.Text;
                m_currentStaff.ZipCode      = TE_ZipCode_TabStaff.Text;
                m_currentStaff.HomePhone    = TE_HomePhone_TabStaff.Text;
                m_currentStaff.CellPhone    = TE_CellPhone_TabStaff.Text;
                m_currentStaff.Fax          = TE_Fax_TabStaff.Text;
                m_currentStaff.Email        = TE_Email_TabStaff.Text;
                m_currentStaff.Remark       = ME_Remark_TabStaff.Text;
                m_currentStaff.SSN          = TE_SSN_TabStaff.Text;

                // set non-Not Null DateTime
                if (String.IsNullOrEmpty(DE_Birth_TabStaff.Text))
                {
                    m_currentStaff.Birth = null;
                }
                else
                {
                    m_currentStaff.Birth = DE_Birth_TabStaff.DateTime;
                }

                // update into database
                s_StaffMgr.Update(m_currentStaff);

                // show result
                showMsg_TabStaff(true, "Update Staff Info Succeed!");

                // refresh staff list
                refreshData_TabStaff(false, true, false, false);
            }
        }

        private void BTN_Delete_TabStaff_Click(object sender, EventArgs e)
        {
            if (m_currentStaff != null && m_currentStaff.id > 0)
            {
                if (MessageBox.Show("Delete this Staff?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
                {
                    // delete this staff and its continue education records
                    deleteStaff(m_currentStaff);

                    // show result
                    showMsg_TabStaff(true, "Staff has been deleted!");

                    // clear controls
                    clearControls_TabStaff();

                    // refresh data
                    refreshData_TabStaff(false, true, false, false);
                }
            }
        }


        private void BTN_Clear_TabStaff_Click(object sender, EventArgs e)
        {
            DE_From_TabStaff.Text       = "";
            DE_To_TabStaff.Text         = "";
            TE_CourseInfo_TabStaff.Text = "";
            TE_Remark2_TabStaff.Text    = "";
        }

        private void BTN_AddCERecord_TabStaff_Click(object sender, EventArgs e)
        {
            // check validity
            if (m_currentStaff == null)
            {
                showMsg_TabStaff(false, "No Staff Selected!");
                return;
            }
            else if (!dxValidationProvider15.Validate())
            {
                showMsg_TabStaff(false, "Continue Education Info Incomplete!");
                return;
            }

            // fill a record
            Model.ContinueEducationRecord record = new Model.ContinueEducationRecord();
            record.StaffID          = m_currentStaff.id;
            record.EducationStart   = DE_From_TabStaff.DateTime;
            record.EducationEnd     = DE_To_TabStaff.DateTime;
            record.CourseInfo       = TE_CourseInfo_TabStaff.Text;
            record.Remark           = TE_Remark2_TabStaff.Text;

            // write to database
            int newID = s_CERecordMgr.Add(record);
            if (newID > 0)
            {
                // show result
                showMsg_TabStaff(true, "Add Continue Education Record Succeed!");

                // refresh
                refreshData_TabStaff(false, false, true, false);

                // go to the last continue education record
                gridView4.MoveLast();
            }
            else
            {
                // show result
                showMsg_TabStaff(false, "Add Continue Education Record Failed!");
            }
        }

        private void BTN_UpdateCERecord_TabStaff_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView4.GetFocusedRow();
            if (row != null && m_currentStaff != null &&
                row["StaffID"].Equals(m_currentStaff.id))
            {
                if (!dxValidationProvider15.Validate())
                {
                    showMsg_TabStaff(false, "Continue Education Info Incomplete!");
                    return;
                }

                // fill a record
                Model.ContinueEducationRecord record = new Model.ContinueEducationRecord();
                record.id               = Int32.Parse(row["id"].ToString());
                record.StaffID          = m_currentStaff.id;
                record.EducationStart   = DE_From_TabStaff.DateTime;
                record.EducationEnd     = DE_To_TabStaff.DateTime;
                record.CourseInfo       = TE_CourseInfo_TabStaff.Text;
                record.Remark           = TE_Remark2_TabStaff.Text;

                // write to database
                s_CERecordMgr.Update(record);

                // show result
                showMsg_TabStaff(true, "Update Continue Education Info Succeed!");

                // save the current position
                int focusRow = gridView4.FocusedRowHandle;

                // refresh
                refreshData_TabStaff(false, false, true, false);

                // set the current position
                gridView4.FocusedRowHandle = focusRow;
            }
            else
            {
                // show result
                showMsg_TabStaff(false, "No Continue Education Record Selected!");
            }
        }

        private void BTN_DelCERecord_TabStaff_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView4.GetFocusedRow();
            if (row != null && m_currentStaff != null && 
                row["StaffID"].Equals(m_currentStaff.id))
            {
                // ask for delete
                if (MessageBox.Show("Delete this Record?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
                {
                    // delete
                    s_CERecordMgr.Delete(Int32.Parse(row["id"].ToString()));

                    // refresh
                    refreshData_TabStaff(false, false, true, false);

                    // go to the last continue education record
                    gridView4.MoveLast();
                }
            }
        }

        private void LU_ServiceType_StaffTab_EditValueChanged(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabStaff();

            // clear m_currentStaff
            m_currentStaff = null;

            // refresh data
            refreshData_TabStaff(false, true, false, false);
        }

        private void LU_Staff_TabStaff_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_Staff_TabStaff.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_Staff_TabStaff.EditValue.ToString());
                    m_currentStaff = s_StaffMgr.GetModel(id);
                    if (m_currentStaff != null)
                    {
                        setLookUpEditText(LU_Sex_TabStaff, m_currentStaff.Sex);
                        setLookUpEditText(LU_Language_TabStaff, m_currentStaff.Language);
                        setLookUpEditText(LU_Drive_TabStaff, (m_currentStaff.Drive) ? "Yes" : "No");
                        setLookUpEditText(LU_Waiting_TabStaff, (m_currentStaff.Waiting) ? "Yes" : "No");

                        TE_Staff2_TabStaff.Text             = m_currentStaff.Name;
                        TE_Allowance_TabStaff.Text          = m_currentStaff.Allowance;
                        DE_StartDate_TabStaff.DateTime      = m_currentStaff.StartWorkDate;
                        DE_EndDate_TabStaff.DateTime        = m_currentStaff.EndWorkDate;
                        TE_ID_TabStaff.Text                 = m_currentStaff.IdentityNo;
                        TE_Address1_TabStaff.Text           = m_currentStaff.AddressLine1;
                        TE_Address2_TabStaff.Text           = m_currentStaff.AddressLine2;
                        TE_ZipCode_TabStaff.Text            = m_currentStaff.ZipCode;
                        TE_HomePhone_TabStaff.Text          = m_currentStaff.HomePhone;
                        TE_CellPhone_TabStaff.Text          = m_currentStaff.CellPhone;
                        TE_Fax_TabStaff.Text                = m_currentStaff.Fax;
                        TE_Email_TabStaff.Text              = m_currentStaff.Email;
                        ME_Remark_TabStaff.Text             = m_currentStaff.Remark;
                        TE_SSN_TabStaff.Text                = m_currentStaff.SSN;

                        // set non-Not Null DateTime
                        if (m_currentStaff.Birth != null)
                        {
                            DE_Birth_TabStaff.DateTime = (DateTime)m_currentStaff.Birth;
                        }
                        else
                        {
                            DE_Birth_TabStaff.Text = "";
                        }

                        // get service name
                        Model.Service service = s_ServiceMgr.GetModel(m_currentStaff.ServiceID);
                        if (service != null)
                        {
                            setLookUpEditText(LU_ServiceType_TabStaff, service.ServiceStr);
                        }

                        // get continue education records
                        refreshData_TabStaff(false, false, true, false);

                        // go to the last auth record
                        gridView4.MoveLast();
                    }
                }
                catch (System.Exception /*ex*/)
                {
                    // if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }
            }
        }

        private void BTN_ShowWorking_TabStaff_Click(object sender, EventArgs e)
        {
            if (LU_ServiceType_TabStaff.EditValue != null)
            {
                // Service type
                int serviceType = Int32.Parse(LU_ServiceType_TabStaff.EditValue.ToString());
                showMsg_TabStaff(true, "Generating Report...");
                showWorkingReport(serviceType);
                showMsg_TabStaff(true, "Report Generated!");
            }
            else
            {
                showMsg_TabStaff(false, "Please Select Service Type!");
                LU_ServiceType_TabStaff.Focus();
            }
        }

        private void BTN_ShowWaiting_TabStaff_Click(object sender, EventArgs e)
        {
            if (LU_ServiceType_TabStaff.EditValue != null)
            {
                // Service type
                int serviceType = Int32.Parse(LU_ServiceType_TabStaff.EditValue.ToString());
                showMsg_TabStaff(true, "Generating Report...");
                showWaitingReport(serviceType);
                showMsg_TabStaff(true, "Report Generated!");
            }
            else
            {
                showMsg_TabStaff(false, "Please Select Service Type!");
                LU_ServiceType_TabStaff.Focus();
            }
        }

        private void gridView4_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DataRowView row = (DataRowView)gridView4.GetFocusedRow();
            if (row != null && m_currentStaff != null &&
                row["StaffID"].Equals(m_currentStaff.id))
            {
                // show current continue education record
                m_currentCERecord = s_CERecordMgr.GetModel(Int32.Parse(row["id"].ToString()));
                if (m_currentCERecord != null)
                {
                    DE_From_TabStaff.DateTime   = m_currentCERecord.EducationStart;
                    DE_To_TabStaff.DateTime     = m_currentCERecord.EducationEnd;
                    TE_CourseInfo_TabStaff.Text = m_currentCERecord.CourseInfo;
                    TE_Remark2_TabStaff.Text    = m_currentCERecord.Remark;
                }
            }
        }
        #endregion

        #region Functions
        // refresh data from database
        private void refreshData_TabStaff(bool bServiceList,
                                          bool bStaffList, 
                                          bool bCERecordList, 
                                          bool bStaticLists)
        {
            // refresh service list
            if (bServiceList)
            {
                m_ServceList_TabStaff = s_ServiceMgr.GetList("Enable=1");

                // bind service names
                if (m_ServceList_TabStaff != null)
                {
                    // bind DataSource
                    LU_ServiceType_TabStaff.Properties.DataSource       = m_ServceList_TabStaff.Tables[0];
                    LU_ServiceType_TabStaff.Properties.DisplayMember    = "Service";
                    LU_ServiceType_TabStaff.Properties.ValueMember      = "id";
                }
            }

            // refresh staff list
            if (bStaffList && LU_ServiceType_TabStaff.EditValue != null)
            {
                // get staff list
                String sid = LU_ServiceType_TabStaff.EditValue.ToString();
                if (!String.IsNullOrEmpty(sid))
                {
                    m_StaffList_TabStaff = s_StaffMgr.GetList("ServiceID=" + sid + " AND Enable=1 ORDER BY Name");
                }
                else
                {
                    m_StaffList_TabStaff = s_StaffMgr.GetList("Enable=1 ORDER BY Name");
                }

                // bind staff names
                if (m_StaffList_TabStaff != null)
                {
                    // bind DataSource
                    LU_Staff_TabStaff.Properties.DataSource     = m_StaffList_TabStaff.Tables[0];
                    LU_Staff_TabStaff.Properties.DisplayMember  = "Name";
                    LU_Staff_TabStaff.Properties.ValueMember    = "id";
                }
            }

            // refresh continue education record list
            if (bCERecordList)
            {
                if (m_currentStaff != null)
                {
                    // set datasource
                    DataSet ds = s_CERecordMgr.GetList("StaffID=" + m_currentStaff.id.ToString());
                    GC_CERecords.DataSource = ds.Tables[0];
                }
            }

            if (bStaticLists)
            {
                // Sex
                DataTable dtSex = new DataTable();
                dtSex.Columns.Add("Sex");
                dtSex.Rows.Add("Female");
                dtSex.Rows.Add("Male");
                LU_Sex_TabStaff.Properties.DataSource       = dtSex;
                LU_Sex_TabStaff.Properties.DisplayMember    = "Sex";
                LU_Sex_TabStaff.Properties.ValueMember      = "Sex";

                // Language
                DataTable dtLanguage = new DataTable();
                dtLanguage.Columns.Add("Language");
                dtLanguage.Rows.Add("Cantones");
                dtLanguage.Rows.Add("English");
                dtLanguage.Rows.Add("Fujianes");
                dtLanguage.Rows.Add("Japanese");
                dtLanguage.Rows.Add("Korean");
                dtLanguage.Rows.Add("Mandarin");
                dtLanguage.Rows.Add("Mingnan");
                dtLanguage.Rows.Add("Russian");
                dtLanguage.Rows.Add("Shanghaines");
                dtLanguage.Rows.Add("Spanish");
                dtLanguage.Rows.Add("Vietnamese");
                dtLanguage.Rows.Add("Others");
                LU_Language_TabStaff.Properties.DataSource = dtLanguage;
                LU_Language_TabStaff.Properties.DisplayMember   = "Language";
                LU_Language_TabStaff.Properties.ValueMember     = "Language";

                // Drive
                DataTable dtDrive = new DataTable();
                dtDrive.Columns.Add("Drive");
                dtDrive.Rows.Add("Yes");
                dtDrive.Rows.Add("No");
                LU_Drive_TabStaff.Properties.DataSource     = dtDrive;
                LU_Drive_TabStaff.Properties.DisplayMember  = "Drive";
                LU_Drive_TabStaff.Properties.ValueMember    = "Drive";

                // Waiting
                DataTable dtWaiting = new DataTable();
                dtWaiting.Columns.Add("Waiting");
                dtWaiting.Rows.Add("Yes");
                dtWaiting.Rows.Add("No");
                LU_Waiting_TabStaff.Properties.DataSource       = dtWaiting;
                LU_Waiting_TabStaff.Properties.DisplayMember    = "Waiting";
                LU_Waiting_TabStaff.Properties.ValueMember      = "Waiting";
            }
        }

        private void clearControls_TabStaff()
        {
            // lookup edits
            clearLookUpEdit(LU_Staff_TabStaff);
            clearLookUpEdit(LU_Sex_TabStaff);
            clearLookUpEdit(LU_Language_TabStaff);
            clearLookUpEdit(LU_Drive_TabStaff);
            clearLookUpEdit(LU_Waiting_TabStaff);

            // clear LU_ServiceType'sEditValue 
            // only if it's empty but not null
            if (LU_ServiceType_TabStaff.EditValue != null && 
                LU_ServiceType_TabStaff.EditValue.Equals(""))
            {
                clearLookUpEdit(LU_ServiceType_TabStaff);
            }

            // textboxes
            TE_Staff_TabStaff.Text          = "";
            TE_ID_TabStaff.Text             = "";
            TE_Allowance_TabStaff.Text      = "";
            DE_StartDate_TabStaff.DateTime  = DateTime.Now;
            DE_EndDate_TabStaff.DateTime    = DateTime.Now;
            TE_Address1_TabStaff.Text       = "";
            TE_Address2_TabStaff.Text       = "";
            TE_ZipCode_TabStaff.Text        = "";
            TE_HomePhone_TabStaff.Text      = "";
            TE_CellPhone_TabStaff.Text      = "";
            TE_Fax_TabStaff.Text            = "";
            TE_Email_TabStaff.Text          = "";
            ME_Remark_TabStaff.Text         = "";
            DE_Birth_TabStaff.Text          = "";
            TE_SSN_TabStaff.Text            = "";

            // continue education controls
            DE_From_TabStaff.Text           = "";
            DE_To_TabStaff.Text             = "";
            TE_CourseInfo_TabStaff.Text     = "";
            TE_Remark2_TabStaff.Text        = "";
            GC_CERecords.DataSource         = null;
        }

        private void changeMode_TabStaff(bool bQueryMode)
        {
            if (bQueryMode)
            {
                // set buttons
                BTN_New_TabStaff.Visible    = true;
                BTN_Update_TabStaff.Enabled = true;
                BTN_Delete_TabStaff.Enabled = true;
                BTN_Submit_TabStaff.Visible = false;
                BTN_Cancel_TabStaff.Visible = false;

                // set input editors
                LU_Staff_TabStaff.Visible   = true;
                TE_Staff_TabStaff.Visible   = false;
                TE_Staff2_TabStaff.Visible  = true;
                LB_Staff2_TabStaff.Visible  = true;
                LB_Staff2Must_TabStaff.Visible  = true;

                // reset validation provider
                resetValidationProvider(dxValidationProvider4);

                // set focus
                LU_ServiceType_TabStaff.Focus();
            }
            else
            {
                // set buttons
                BTN_New_TabStaff.Visible    = false;
                BTN_Update_TabStaff.Enabled = false;
                BTN_Delete_TabStaff.Enabled = false;
                BTN_Submit_TabStaff.Visible = true;
                BTN_Cancel_TabStaff.Visible = true;

                 // set input editors
                LU_Staff_TabStaff.Visible   = false;
                TE_Staff_TabStaff.Visible   = true;
                TE_Staff2_TabStaff.Visible  = false;
                LB_Staff2_TabStaff.Visible  = false;
                LB_Staff2Must_TabStaff.Visible = false;

                // set focus
                LU_ServiceType_TabStaff.Focus();
            }
        }

        private void showWorkingReport(int serviceType)
        {
            DataSet ds = s_StaffMgr.GetList2("Enable = 1 AND Waiting = 0 And ServiceID = " + serviceType.ToString() + " ORDER BY Name");
            //ds.WriteXmlSchema("c:\\1.xsd");

            // output ds
            // create report
            XRWorkingStaff report = new XRWorkingStaff(ds);
            report.ShowPreview();
        }

        private void showWaitingReport(int serviceType)
        {
            DataSet ds = s_StaffMgr.GetList2("Enable = 1 AND Waiting = 1 And ServiceID = " + serviceType.ToString() + " ORDER BY Name");
            //ds.WriteXmlSchema("c:\\1.xsd");

            // output ds
            // create report
            XRWaitingStaff report = new XRWaitingStaff(ds);
            report.ShowPreview();
        }

        private void deleteStaff(Model.Staff staffToDelete)
        {
            staffToDelete.Enable = false;
            s_StaffMgr.Update(staffToDelete);

            // delete continue education related to this Staff
            List<Model.ContinueEducationRecord> records = s_CERecordMgr.GetModelList("StaffID=" + staffToDelete.id);
            for (int i = 0; i < records.Count; i++)
            {
                s_CERecordMgr.Delete(records[i].id);
            }
        }

        private void showMsg_TabStaff(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success_TabStaff.ForeColor = Color.Green;
            }
            else
            {
                LB_Success_TabStaff.ForeColor = Color.Red;
            }

            LB_Success_TabStaff.Text = msg;
            LB_Success_TabStaff.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success_TabStaff.Size.Width / 2),
                                                     LB_Success_TabStaff.Location.Y);
        }
        #endregion

        #region Members
        private bool m_firstLoad_TabStaff       = true;
        private Model.Staff m_currentStaff      = null;
        private DataSet m_ServceList_TabStaff   = null;
        private DataSet m_StaffList_TabStaff    = null;
        private Model.ContinueEducationRecord m_currentCERecord = null;
        #endregion
        #endregion

        #region TabServices
        #region EventHandlers
        private void BTN_New_TabServices_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabServices();

            // change mode
            changeMode_TabServices(false);
        }

        private void BTN_Cancel_TabServices_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabServices();

            // change mode
            changeMode_TabServices(true);
        }

        private void BTN_Submit_TabServices_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider6.Validate())
            {
                showMsg_TabServices(false, "Service Info Incomplete!");
                return;
            }

            // fill in service object
            Model.Service service   = new Model.Service();
            service.ServiceStr      = TE_ServiceType_TabServices.Text;
            service.Enable          = true;
            service.Remark          = ME_Remark_TabServices.Text;

            // write to database
            int newID = s_ServiceMgr.Add(service);
            if (newID > 0)
            {
                // show result
                showMsg_TabServices(true, "Add Service Succeed!");

                // clear controls
                clearControls_TabServices();

                // change mode
                changeMode_TabServices(true);

                // refresh service list
                refreshData_TabServices(true);

                // show newly add service
                LU_ServiceType_TabServices.EditValue = newID;
            }
            else
            {
                // show result
                showMsg_TabServices(false, "Add Service Failed!");
            }
        }

        private void BTN_Update_TabServices_Click(object sender, EventArgs e)
        {
            // check validity
            //if (!dxValidationProvider5.Validate())
            //{
            //    showMsg_TabStaff(false, "Staff Info Incomplete!");
            //    return;
            //}

            if (m_currentService != null && m_currentService.id > 0)
            {
                // fill in current service
                //m_currentService.ServiceStr = TE_ServiceType_TabServices.Text;
                m_currentService.Enable     = true;
                m_currentService.Remark     = ME_Remark_TabServices.Text;

                // update into database
                s_ServiceMgr.Update(m_currentService);

                // show result
                showMsg_TabServices(true, "Update Service Info Succeed!");
            }
        }

        private void BTN_Delete_TabServices_Click(object sender, EventArgs e)
        {
            if (m_currentService != null && m_currentService.id > 0)
            {
                if (MessageBox.Show("Delete this Service?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    // delete this service and its Staffs
                    deleteService(m_currentService);

                    // show result
                    showMsg_TabServices(true, "Service has been deleted!");

                    // clear controls
                    clearControls_TabServices();

                    // refresh data
                    refreshData_TabServices(true);
                }
            }
        }

        private void LU_ServiceType_TabServices_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_ServiceType_TabServices.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_ServiceType_TabServices.EditValue.ToString());
                    m_currentService = s_ServiceMgr.GetModel(id);
                    if (m_currentService != null)
                    {
                        ME_Remark_TabServices.Text = m_currentService.Remark;
                    }
                }
                catch (System.Exception /*ex*/)
                {
                	// if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }
            }
        }
        #endregion

        #region Functions
        // refresh data from database
        private void refreshData_TabServices(bool bServiceList)
        {
            // refresh service list
            if (bServiceList)
            {
                m_ServceList_TabServices = s_ServiceMgr.GetList("Enable=1");

                // bind service names
                if (m_ServceList_TabServices != null)
                {
                    // bind DataSource
                    LU_ServiceType_TabServices.Properties.DataSource    = m_ServceList_TabServices.Tables[0];
                    LU_ServiceType_TabServices.Properties.DisplayMember = "Service";
                    LU_ServiceType_TabServices.Properties.ValueMember   = "id";
                }
            }
        }

        private void clearControls_TabServices()
        {
            // lookup edits
            clearLookUpEdit(LU_ServiceType_TabServices);

            // textboxes
            TE_ServiceType_TabServices.Text = "";
            ME_Remark_TabServices.Text      = "";
        }

        private void changeMode_TabServices(bool bQueryMode)
        {
            if (bQueryMode)
            {
                // set buttons
                BTN_New_TabServices.Visible     = true;
                BTN_Update_TabServices.Enabled  = true;
                BTN_Delete_TabServices.Enabled  = true;
                BTN_Submit_TabServices.Visible  = false;
                BTN_Cancel_TabServices.Visible  = false;

                // set input editors
                LU_ServiceType_TabServices.Visible = true;
                TE_ServiceType_TabServices.Visible = false;
                
                // reset validation provider
                resetValidationProvider(dxValidationProvider6);

                // set focus
                LU_ServiceType_TabServices.Focus();
            }
            else
            {
                // set buttons
                BTN_New_TabServices.Visible     = false;
                BTN_Update_TabServices.Enabled  = false;
                BTN_Delete_TabServices.Enabled  = false;
                BTN_Submit_TabServices.Visible  = true;
                BTN_Cancel_TabServices.Visible  = true;

                // set input editors
                LU_ServiceType_TabServices.Visible = false;
                TE_ServiceType_TabServices.Visible = true; ;

                // set focus
                TE_ServiceType_TabServices.Focus();
            }
        }

        private void deleteService(Model.Service serviceToDelete)
        {
            serviceToDelete.Enable = false;
            s_ServiceMgr.Update(serviceToDelete);

            // delete staffs related to this Service
            List<Model.Staff> staffs = s_StaffMgr.GetModelList("ServiceID=" + serviceToDelete.id);
            for (int i = 0; i < staffs.Count; i++)
            {
                deleteStaff(staffs[i]);
            }
        }

        private void showMsg_TabServices(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success_TabServices.ForeColor = Color.Green;
            }
            else
            {
                LB_Success_TabServices.ForeColor = Color.Red;
            }

            LB_Success_TabServices.Text = msg;
            LB_Success_TabServices.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success_TabServices.Size.Width / 2),
                                                        LB_Success_TabServices.Location.Y);
        }
        #endregion

        #region Members
        private bool m_firstLoad_TabServices        = true;
        private Model.Service m_currentService      = null;
        private DataSet m_ServceList_TabServices    = null;
        #endregion
        #endregion

        #region TabCompanies
        #region EventHandlers
        private void BTN_New_TabCompanies_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabCompanies();

            // change mode
            changeMode_TabCompanies(false);
        }

        private void BTN_Cancel_TabCompanies_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabCompanies();

            // change mode
            changeMode_TabCompanies(true);
        }

        private void BTN_Submit_TabCompanies_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider7.Validate())
            {
                showMsg_TabCompanies(false, "Company Info Incomplete!");
                return;
            }

            // check unit rate
            double unitRate = 0;
            try
            {
                unitRate = Double.Parse(TE_UnitRate_TabCompanies.Text);
                if (unitRate < 0)
                {
                    showMsg_TabCompanies(false, "Unit Rate Invalid!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg_TabCompanies(false, "Unit Rate Invalid!");
                return;
            }

            // fill in company object
            Model.Company company   = new Model.Company();
            company.CompanyStr      = TE_Company_TabCompanies.Text;
            company.Enable          = true;
            company.UnitRate        = unitRate.ToString();
            company.Remark          = ME_Remark_TabCompanies.Text;

            // write to database
            int newID = s_CompanyMgr.Add(company);
            if (newID > 0)
            {
                // show result
                showMsg_TabCompanies(true, "Add Company Succeed!");

                // clear controls
                clearControls_TabCompanies();

                // change mode
                changeMode_TabCompanies(true);

                // refresh company list
                refreshData_TabCompanies(true);

                // show newly add company
                LU_Company_TabCompanies.EditValue = newID;
            }
            else
            {
                // show result
                showMsg_TabCompanies(false, "Add Company Failed!");
            }
        }

        private void BTN_Update_TabCompanies_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider8.Validate())
            {
                showMsg_TabStaff(false, "Company Info Incomplete!");
                return;
            }

            // check unit rate
            double unitRate = 0;
            try
            {
                unitRate = Double.Parse(TE_UnitRate_TabCompanies.Text);
                if (unitRate < 0)
                {
                    showMsg_TabCompanies(false, "Unit Rate Invalid!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg_TabCompanies(false, "Unit Rate Invalid!");
                return;
            }

            if (m_currentCompany != null && m_currentCompany.id > 0)
            {
                // fill in current company
                 //m_currentCompany.CompanyStr   = TE_Company_TabCompanies.Text;
                m_currentCompany.Enable         = true;
                m_currentCompany.UnitRate       = unitRate.ToString();
                m_currentCompany.Remark         = ME_Remark_TabCompanies.Text;

                // update into database
                s_CompanyMgr.Update(m_currentCompany);

                // show result
                showMsg_TabCompanies(true, "Update Company Info Succeed!");
            }
        }

        private void BTN_Delete_TabCompanies_Click(object sender, EventArgs e)
        {
            if (m_currentCompany != null && m_currentCompany.id > 0)
            {
                if (MessageBox.Show("Delete this Company?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    m_currentCompany.Enable = false;

                    // update into database
                    s_CompanyMgr.Update(m_currentCompany);

                    // show result
                    showMsg_TabCompanies(true, "Company has been deleted!");

                    // clear controls
                    clearControls_TabCompanies();

                    // refresh data
                    refreshData_TabCompanies(true);
                }
            }
        }

        private void LU_Company_TabCompanies_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_Company_TabCompanies.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_Company_TabCompanies.EditValue.ToString());
                    m_currentCompany = s_CompanyMgr.GetModel(id);
                    if (m_currentCompany != null)
                    {
                        TE_UnitRate_TabCompanies.Text   = m_currentCompany.UnitRate.ToString();
                        ME_Remark_TabCompanies.Text     = m_currentCompany.Remark;
                    }
                }
                catch (System.Exception /*ex*/)
                {
                	// if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }

            }
        }
        #endregion

        #region Functions
        // refresh data from database
        private void refreshData_TabCompanies(bool bCompanyList)
        {
            // refresh company list
            if (bCompanyList)
            {
                m_CompanyList_TabCompanies = s_CompanyMgr.GetList("Enable=1");

                // bind company names
                if (m_CompanyList_TabCompanies != null)
                {
                    // bind DataSource
                    LU_Company_TabCompanies.Properties.DataSource       = m_CompanyList_TabCompanies.Tables[0];
                    LU_Company_TabCompanies.Properties.DisplayMember    = "Company";
                    LU_Company_TabCompanies.Properties.ValueMember      = "id";
                }
            }
        }

        private void clearControls_TabCompanies()
        {
            // lookup edits
            clearLookUpEdit(LU_Company_TabCompanies);

            // textboxes
            TE_Company_TabCompanies.Text    = "";
            TE_UnitRate_TabCompanies.Text   = "";
            ME_Remark_TabCompanies.Text     = "";
        }

        private void changeMode_TabCompanies(bool bQueryMode)
        {
            if (bQueryMode)
            {
                // set buttons
                BTN_New_TabCompanies.Visible    = true;
                BTN_Update_TabCompanies.Enabled = true;
                BTN_Delete_TabCompanies.Enabled = true;
                BTN_Submit_TabCompanies.Visible = false;
                BTN_Cancel_TabCompanies.Visible = false;

                // set input editors
                LU_Company_TabCompanies.Visible = true;
                TE_Company_TabCompanies.Visible = false;

                // reset validation provider
                resetValidationProvider(dxValidationProvider7);

                // set focus
                LU_Company_TabCompanies.Focus();
            }
            else
            {
                // set buttons
                BTN_New_TabCompanies.Visible    = false;
                BTN_Update_TabCompanies.Enabled = false;
                BTN_Delete_TabCompanies.Enabled = false;
                BTN_Submit_TabCompanies.Visible = true;
                BTN_Cancel_TabCompanies.Visible = true;

                // set input editors
                LU_Company_TabCompanies.Visible = false;
                TE_Company_TabCompanies.Visible = true; ;

                // set focus
                TE_Company_TabCompanies.Focus();
            }
        }

        private void showMsg_TabCompanies(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success_TabCompanies.ForeColor = Color.Green;
            }
            else
            {
                LB_Success_TabCompanies.ForeColor = Color.Red;
            }

            LB_Success_TabCompanies.Text = msg;
            LB_Success_TabCompanies.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success_TabCompanies.Size.Width / 2),
                                                         LB_Success_TabCompanies.Location.Y);
        }
        #endregion

        #region Members
        private bool m_firstLoad_TabCompanies       = true;
        private Model.Company m_currentCompany      = null;
        private DataSet m_CompanyList_TabCompanies  = null;
        #endregion
        #endregion

        #region TabInvoice
        #region EventHandlers
        private void BTN_New_TabInvoice_Click(object sender, EventArgs e)
        {
            // clear controls partially
            clearControls2_TabInvoice();

            // change mode
            changeMode_TabInvoice(false);
        }

        private void BTN_Cancel_TabInvoice_Click(object sender, EventArgs e)
        {
            // clear controls
            clearControls_TabInvoice();

            // change mode
            changeMode_TabInvoice(true);
        }

        private void BTN_Submit_TabInvoice_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider10.Validate())
            {
                showMsg_TabInvoice(false, "Invoice Info Incomplete!");
                return;
            }

            // check amount
            double amount = 0;
            try
            {
                amount = Double.Parse(TE_Amount_TabInvoice.Text);
                if (amount < 0)
                {
                    showMsg_TabInvoice(false, "Invalid Amount!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg_TabInvoice(false, "Invalid Amount!");
                return;
            }

            // check if the invoice number already exists
            String invoiceNumber = TE_InvoiceNumber_TabInvoice.Text;
            List<Model.Invoice> dupInvoice = s_InvoiceMgr.GetModelList("InvoiceNumber='" + invoiceNumber + "' AND Enable=1");
            if (dupInvoice.Count > 0)
            {
                showMsg_TabInvoice(false, "Invoice Number Already Exists!");
                return;
            }

            // fill in invoice object
            Model.Invoice invoice   = new Model.Invoice();
            invoice.Enable          = true;
            invoice.InvoiceNumber   = TE_InvoiceNumber_TabInvoice.Text;
            invoice.PatientID       = Int32.Parse(LU_Patient_TabInvoice.EditValue.ToString());
            invoice.Amount          = amount.ToString();
            invoice.InvoiceDate     = DE_InvoiceDate_TabInvoice.DateTime;
            invoice.MailDate        = DE_MailDate_TabInvoice.DateTime;
            invoice.Remark          = ME_Remark_TabInvoice.Text;
            invoice.AuthorizationCode = TE_PatientID_TabInvoice.Text;   // use AuthCode to store PatientID
            invoice.ServiceCode     = LU_ServiceCode_TabInvoice.Text;
            invoice.ServiceType     = LU_ServiceType_TabInvoice.EditValue.ToString();

            // set non-Not Null DateTime
            if (String.IsNullOrEmpty(DE_ServiceFrom_TabInvoice.Text))
            {
                invoice.ServiceStart = null;
            }
            else
            {
                invoice.ServiceStart = DE_ServiceFrom_TabInvoice.DateTime;
            }
            if (String.IsNullOrEmpty(DE_ServiceTo_TabInvoice.Text))
            {
                invoice.ServiceEnd = null;
            }
            else
            {
                invoice.ServiceEnd = DE_ServiceTo_TabInvoice.DateTime;
            }

            // write to database
            int newID = s_InvoiceMgr.Add(invoice);
            if (newID > 0)
            {
                // show result
                showMsg_TabInvoice(true, "Add Invoice Succeed!");

                // clear controls
                clearControls_TabInvoice();

                // change mode
                changeMode_TabInvoice(true);

                // refresh invoice list
                refreshData_TabInvoice(true, false, false, false);

                // show newly add staff
                LU_InvoiceNumber_TabInvoice.EditValue = newID;
            }
            else
            {
                // show result
                showMsg_TabInvoice(false, "Add Invoice Failed!");
            }
        }

        private void BTN_Update_TabInvoice_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider11.Validate())
            {
                showMsg_TabInvoice(false, "Invoice Info Incomplete!");
                return;
            }

            // check amount
            double amount = 0;
            try
            {
                amount = Double.Parse(TE_Amount_TabInvoice.Text);
                if (amount < 0)
                {
                    showMsg_TabInvoice(false, "Invalid Amount!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg_TabInvoice(false, "Invalid Amount!");
                return;
            }

            // check if the invoice number already exists
            //String invoiceNumber = TE_InvoiceNumber_TabInvoice.Text;
            //List<Model.Invoice> dupInvoice = s_InvoiceMgr.GetModelList("InvoiceNumber='" + invoiceNumber + "'");
            //if (dupInvoice.Count > 0)
            //{
            //    showMsg_TabInvoice(false, "Invoice Number Already Exists!");
            //    return;
            //}

            if (m_currentInvoice != null && m_currentInvoice.id > 0)
            {
                // fill in current staff
                //m_currentInvoice.InvoiceNumber = TE_InvoiceNumber_TabInvoice.Text;
                //m_currentInvoice.PatientID      = Int32.Parse(LU_Patient_TabInvoice.EditValue.ToString());
                m_currentInvoice.Amount         = amount.ToString();
                m_currentInvoice.InvoiceDate    = DE_InvoiceDate_TabInvoice.DateTime;
                m_currentInvoice.MailDate       = DE_MailDate_TabInvoice.DateTime;
                m_currentInvoice.Remark         = ME_Remark_TabInvoice.Text;
                m_currentInvoice.AuthorizationCode = TE_PatientID_TabInvoice.Text;  // use AuthCode to store PatientID
                m_currentInvoice.ServiceCode    = LU_ServiceCode_TabInvoice.Text;
                m_currentInvoice.ServiceType    = LU_ServiceType_TabInvoice.EditValue.ToString();

                // set non-Not Null DateTime
                if (String.IsNullOrEmpty(DE_ServiceFrom_TabInvoice.Text))
                {
                    m_currentInvoice.ServiceStart = null;
                }
                else
                {
                    m_currentInvoice.ServiceStart = DE_ServiceFrom_TabInvoice.DateTime;
                }
                if (String.IsNullOrEmpty(DE_ServiceTo_TabInvoice.Text))
                {
                    m_currentInvoice.ServiceEnd = null;
                }
                else
                {
                    m_currentInvoice.ServiceEnd = DE_ServiceTo_TabInvoice.DateTime;
                }

                // this is added to resolve the strange change of patient name 
                // when updating invoice data without changing the patient name
                // only update m_currentInvoice.PatientID when patient name 
                // have changed explicitly by user
                if (m_patientNameChanged_TabInvoice)
                {
                    m_currentInvoice.PatientID = Int32.Parse(LU_Patient_TabInvoice.EditValue.ToString());
                }
                m_patientNameChanged_TabInvoice = false;

                // update into database
                s_InvoiceMgr.Update(m_currentInvoice);

                // show result
                showMsg_TabInvoice(true, "Update Invoice Info Succeed!");
            }
        }

        private void BTN_Delete_TabInvoice_Click(object sender, EventArgs e)
        {
            if (m_currentInvoice != null && m_currentInvoice.id > 0)
            {
                if (MessageBox.Show("Delete this Invoice?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    // delete invoice and all its payments
                    deleteInvoice(m_currentInvoice);

                    // show result
                    showMsg_TabInvoice(true, "Invoice has been deleted!");

                    // clear controls
                    clearControls_TabInvoice();

                    // refresh data
                    refreshData_TabInvoice(true, false, false, false);
                }
            }
        }

        private void LU_InvoiceNumber_TabInvoice_EditValueChanged(object sender, EventArgs e)
        {
            if (LU_InvoiceNumber_TabInvoice.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_InvoiceNumber_TabInvoice.EditValue.ToString());
                    m_currentInvoice = s_InvoiceMgr.GetModel(id);
                    if (m_currentInvoice != null)
                    {
                        setLookUpEditText(LU_ServiceType_TabInvoice, m_currentInvoice.ServiceType);
                        setLookUpEditText(LU_ServiceCode_TabInvoice, m_currentInvoice.ServiceCode);

                        TE_Amount_TabInvoice.Text           = m_currentInvoice.Amount;
                        DE_InvoiceDate_TabInvoice.DateTime  = m_currentInvoice.InvoiceDate;
                        DE_MailDate_TabInvoice.DateTime     = m_currentInvoice.MailDate;
                        ME_Remark_TabInvoice.Text           = m_currentInvoice.Remark;
                        TE_PatientID_TabInvoice.Text        = m_currentInvoice.AuthorizationCode;   // read PatientID from AuthCode

                        // set non-Not Null DateTime
                        if (m_currentInvoice.ServiceStart != null)
                        {
                            DE_ServiceFrom_TabInvoice.DateTime = (DateTime)m_currentInvoice.ServiceStart;
                        }
                        else
                        {
                            DE_ServiceFrom_TabInvoice.Text = "";
                        }
                        if (m_currentInvoice.ServiceEnd != null)
                        {
                            DE_ServiceTo_TabInvoice.DateTime = (DateTime)m_currentInvoice.ServiceEnd;
                        }
                        else
                        {
                            DE_ServiceTo_TabInvoice.Text = "";
                        }

                        // get patient name
                        Model.Patient patient = s_PatientMgr.GetModel(m_currentInvoice.PatientID);
                        if (patient != null)
                        {
                            setLookUpEditText(LU_Patient_TabInvoice, patient.LastName + "," + patient.FirstName);
                        }

                        // this is added to resolve the strange change of patient name 
                        // when updating invoice data without changing the patient name
                        m_patientNameChanged_TabInvoice = false;

                        // get payment list
                        refreshData_TabInvoice(false, false, true, false);
                    }
                }
                catch (System.Exception /*ex*/)
                {
                    // if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }
            }
        }

        private void BTN_Clear_TabInvoice_Click(object sender, EventArgs e)
        {
            TE_Received_TabInvoice.Text     = "";
            DE_Received_TabInvoice.DateTime = DateTime.Now;
            TE_CheckNumber_TabInvoice.Text  = "";
            TE_Remark2_TabInvoice.Text      = "";
        }

        private void BTN_DeletePayment_TabInvoice_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView3.GetFocusedRow();
            if (row != null && m_currentInvoice != null &&
                row["InvoiceID"].Equals(m_currentInvoice.id))
            {
                // ask for delete
                if (MessageBox.Show("Delete this Payment?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    // delete
                    s_PaymentMgr.Delete(Int32.Parse(row["id"].ToString()));

                    // refresh
                    refreshData_TabInvoice(false, false, true, false);
                }
            }
        }

        private void BTN_AddPayment_TabInvoice_Click(object sender, EventArgs e)
        {
            // check validity
            if (m_currentInvoice == null)
            {
                showMsg_TabInvoice(false, "No Invoice Selected!");
                return;
            }
            else if (!dxValidationProvider12.Validate())
            {
                showMsg_TabInvoice(false, "Payment Info Incomplete!");
                return;
            }
      
            // check received
            double received = 0;
            try
            {
                received = Double.Parse(TE_Received_TabInvoice.Text);
                if (received < 0)
                {
                    showMsg_TabInvoice(false, "Invalid Received Amount!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg_TabInvoice(false, "Invalid Received Amount!");
                return;
            }

            // fill a payment
            Model.Payment payment   = new Model.Payment();
            payment.InvoiceID       = m_currentInvoice.id;
            payment.Received        = received.ToString();
            payment.ReceivedDate    = DE_Received_TabInvoice.DateTime;
            payment.CheckNumber     = TE_CheckNumber_TabInvoice.Text;
            payment.Remark          = TE_Remark2_TabInvoice.Text;

            // write to database
            int newID = s_PaymentMgr.Add(payment);
            if (newID > 0)
            {
                // show result
                showMsg_TabInvoice(true, "Add Payment Succeed!");

                // refresh
                refreshData_TabInvoice(false, false, true, false);
            }
            else
            {
                // show result
                showMsg_TabInvoice(false, "Add Payment Failed!");
            }
        }

        private void BTN_UpdatePayment_TabInvoice_Click(object sender, EventArgs e)
        {
            DataRowView row = (DataRowView)gridView3.GetFocusedRow();
            if (row != null && m_currentInvoice != null &&
                row["InvoiceID"].Equals(m_currentInvoice.id))
            {
                if (!dxValidationProvider12.Validate())
                {
                    showMsg_TabInvoice(false, "Payment Info Incomplete!");
                    return;
                }

                // check received
                double received = 0;
                try
                {
                    received = Double.Parse(TE_Received_TabInvoice.Text);
                    if (received < 0)
                    {
                        showMsg_TabInvoice(false, "Invalid Received Amount!");
                        return;
                    }
                }
                catch (System.Exception)
                {
                    showMsg_TabInvoice(false, "Invalid Received Amount!");
                    return;
                }

                // fill a payment
                Model.Payment payment   = new Model.Payment();
                payment.id              = Int32.Parse(row["id"].ToString());
                payment.InvoiceID       = m_currentInvoice.id;
                payment.Received        = received.ToString();
                payment.ReceivedDate    = DE_Received_TabInvoice.DateTime;
                payment.CheckNumber     = TE_CheckNumber_TabInvoice.Text;
                payment.Remark          = TE_Remark2_TabInvoice.Text;

                // write to database
                s_PaymentMgr.Update(payment);

                // show result
                showMsg_TabInvoice(true, "Update Payment Info Succeed!");

                // refresh
                refreshData_TabInvoice(false, false, true, false);
            }
            else
            {
                // show result
                showMsg_TabInvoice(false, "No Payment Selected!");
            }
        }

        private void BTN_LastHHA_TabInvoice_Click(object sender, EventArgs e)
        {
            String lastInvoiceNumber    = null;
            DateTime lastInvoiceDate    = DateTime.Now;
            getLastInvoiceNumber('0', out lastInvoiceNumber, out lastInvoiceDate);
            showLastInvoiceNumber(lastInvoiceNumber, lastInvoiceDate);
        }

        private void BTN_LastRN_TabInvoice_Click(object sender, EventArgs e)
        {
            String lastInvoiceNumber    = null;
            DateTime lastInvoiceDate    = DateTime.Now;
            getLastInvoiceNumber('1', out lastInvoiceNumber, out lastInvoiceDate);
            showLastInvoiceNumber(lastInvoiceNumber, lastInvoiceDate);
        }

        private void BTN_LastPT_TabInvoice_Click(object sender, EventArgs e)
        {
            String lastInvoiceNumber    = null;
            DateTime lastInvoiceDate    = DateTime.Now;
            getLastInvoiceNumber('2', out lastInvoiceNumber, out lastInvoiceDate);
            showLastInvoiceNumber(lastInvoiceNumber, lastInvoiceDate);
        }

        private void BTN_LastSW_TabInvoice_Click(object sender, EventArgs e)
        {
            String lastInvoiceNumber    = null;
            DateTime lastInvoiceDate    = DateTime.Now;
            getLastInvoiceNumber('3', out lastInvoiceNumber, out lastInvoiceDate);
            showLastInvoiceNumber(lastInvoiceNumber, lastInvoiceDate);
        }

        private void BTN_LastNutrition_TabInvoice_Click(object sender, EventArgs e)
        {
            String lastInvoiceNumber = null;
            DateTime lastInvoiceDate = DateTime.Now;
            getLastInvoiceNumber('4', out lastInvoiceNumber, out lastInvoiceDate);
            showLastInvoiceNumber(lastInvoiceNumber, lastInvoiceDate);
        }

        private void gridView3_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            DataRowView row = (DataRowView)gridView3.GetFocusedRow();
            if (row != null && m_currentInvoice != null &&
                row["InvoiceID"].Equals(m_currentInvoice.id))
            {
                // show current payment
                Model.Payment payment =
                    s_PaymentMgr.GetModel(Int32.Parse(row["id"].ToString()));
                if (payment != null)
                {
                    TE_Received_TabInvoice.Text     = payment.Received;
                    TE_CheckNumber_TabInvoice.Text  = payment.CheckNumber;
                    TE_Remark2_TabInvoice.Text      = payment.Remark;
                    DE_Received_TabInvoice.DateTime = payment.ReceivedDate;
                }
            }
        }

        // this is added to resolve the strange change of patient name 
        // when updating invoice data without changing the patient name
        private void LU_Patient_TabInvoice_EditValueChanged(object sender, EventArgs e)
        {
            m_patientNameChanged_TabInvoice = true;

            // show patient ID accordingly
            if (LU_Patient_TabInvoice.EditValue != null)
            {
                try
                {
                    int id = Int32.Parse(LU_Patient_TabInvoice.EditValue.ToString());
                    Model.Patient patient = s_PatientMgr.GetModel(id);
                    if (patient != null && patient.Enable)
                    {
                        // set Patient ID
                        TE_PatientID_TabInvoice.Text = patient.IdentityNo;
                    }
                }
                catch (System.Exception /*ex*/)
                {
                    // if pasted a missing item, the EditValue would be the 
                    // item string, thus causing an exception at Int32.Parse
                }
            }
        }
        #endregion

        #region Functions
        // refresh data from database
        private void refreshData_TabInvoice(bool bInvoiceList,
                                            bool bPatientList,
                                            bool bPaymentList, 
                                            bool bStaticLists)
        {
            // refresh service list
            if (bInvoiceList)
            {
                m_InvoiceList_TabInvoice = s_InvoiceMgr.GetList("Enable=1 ORDER BY InvoiceNumber");

                // bind invoice number
                if (m_InvoiceList_TabInvoice != null)
                {
                    // bind DataSource
                    LU_InvoiceNumber_TabInvoice.Properties.DataSource       = m_InvoiceList_TabInvoice.Tables[0];
                    LU_InvoiceNumber_TabInvoice.Properties.DisplayMember    = "InvoiceNumber";
                    LU_InvoiceNumber_TabInvoice.Properties.ValueMember      = "id";
                }
            }

            // refresh patient list
            if (bPatientList)
            {
                m_PatientList_TabInvoice = s_PatientMgr.GetNames("Enable=1");

                // bind patient names
                if (m_PatientList_TabInvoice != null)
                {
                    // bind DataSource
                    LU_Patient_TabInvoice.Properties.DataSource     = m_PatientList_TabInvoice.Tables[0];
                    LU_Patient_TabInvoice.Properties.DisplayMember  = "LastName";
                    LU_Patient_TabInvoice.Properties.ValueMember    = "id";
                }
            }

            // refresh payment list
            if (bPaymentList)
            {
                if (m_currentInvoice != null)
                {
                    DataSet ds = s_PaymentMgr.GetList("InvoiceID=" + m_currentInvoice.id.ToString());
                    GC_Payment.DataSource = ds.Tables[0];
                    gridView3.MoveLast();
                }
            }

            if (bStaticLists)
            {
                // Service Type
                DataTable dtService = new DataTable();
                dtService.Columns.Add("Service");
                dtService.Rows.Add("HHA");
                dtService.Rows.Add("Other Services");
                LU_ServiceType_TabInvoice.Properties.DataSource     = dtService;
                LU_ServiceType_TabInvoice.Properties.DisplayMember  = "Service";
                LU_ServiceType_TabInvoice.Properties.ValueMember    = "Service";

                // Service Code
                DataTable dtServiceCode = new DataTable();
                dtServiceCode.Columns.Add("ServiceCode");
                dtServiceCode.Rows.Add("T1001");
                dtServiceCode.Rows.Add("T1019");
                dtServiceCode.Rows.Add("T1030");
                dtServiceCode.Rows.Add("S9122");
                dtServiceCode.Rows.Add("S9123");
                dtServiceCode.Rows.Add("S9127");
                dtServiceCode.Rows.Add("S9129");
                dtServiceCode.Rows.Add("S9131");
                dtServiceCode.Rows.Add("S9470");
                dtServiceCode.Rows.Add("PCAH1");
                dtServiceCode.Rows.Add("99082");
                dtServiceCode.Rows.Add("LIPCA");
                LU_ServiceCode_TabInvoice.Properties.DataSource     = dtServiceCode;
                LU_ServiceCode_TabInvoice.Properties.DisplayMember  = "ServiceCode";
                LU_ServiceCode_TabInvoice.Properties.ValueMember    = "ServiceCode";
            }
        }

        private void clearControls_TabInvoice()
        {
            // lookup edits
            clearLookUpEdit(LU_InvoiceNumber_TabInvoice);
            clearLookUpEdit(LU_Patient_TabInvoice);
            clearLookUpEdit(LU_ServiceType_TabInvoice);
            clearLookUpEdit(LU_ServiceCode_TabInvoice);

            // textboxes
            TE_InvoiceNumber_TabInvoice.Text    = "";
            TE_Amount_TabInvoice.Text           = "";
            DE_InvoiceDate_TabInvoice.DateTime  = DateTime.Now;
            DE_MailDate_TabInvoice.DateTime     = DateTime.Now;
            ME_Remark_TabInvoice.Text           = "";
            TE_PatientID_TabInvoice.Text        = "";
            DE_ServiceFrom_TabInvoice.Text      = "";
            DE_ServiceTo_TabInvoice.Text        = "";

             // payment controls
            TE_Received_TabInvoice.Text         = "";
            DE_Received_TabInvoice.DateTime     = DateTime.Now;
            TE_CheckNumber_TabInvoice.Text      = "";
            TE_Remark2_TabInvoice.Text          = "";
            GC_Payment.DataSource               = null;
        }

        // partial clear
        private void clearControls2_TabInvoice()
        {
            // lookup edits
            clearLookUpEdit(LU_InvoiceNumber_TabInvoice);
            clearLookUpEdit(LU_Patient_TabInvoice);
            //clearLookUpEdit(LU_ServiceType_TabInvoice);
            //clearLookUpEdit(LU_ServiceCode_TabInvoice);

            // textboxes
            TE_InvoiceNumber_TabInvoice.Text = "";
            TE_Amount_TabInvoice.Text = "";
            //DE_InvoiceDate_TabInvoice.DateTime = DateTime.Now;
            //DE_MailDate_TabInvoice.DateTime = DateTime.Now;
            //ME_Remark_TabInvoice.Text = "";
            TE_PatientID_TabInvoice.Text = "";
            //DE_ServiceFrom_TabInvoice.Text = "";
            //DE_ServiceTo_TabInvoice.Text = "";

            // payment controls
            TE_Received_TabInvoice.Text = "";
            DE_Received_TabInvoice.DateTime = DateTime.Now;
            TE_CheckNumber_TabInvoice.Text = "";
            TE_Remark2_TabInvoice.Text = "";
            GC_Payment.DataSource = null;
        }

        private void changeMode_TabInvoice(bool bQueryMode)
        {
            if (bQueryMode)
            {
                // set buttons
                BTN_New_TabInvoice.Visible      = true;
                BTN_Update_TabInvoice.Enabled   = true;
                BTN_Delete_TabInvoice.Enabled   = true;
                BTN_Submit_TabInvoice.Visible   = false;
                BTN_Cancel_TabInvoice.Visible   = false;

                // set input editors
                LU_InvoiceNumber_TabInvoice.Visible = true;
                TE_InvoiceNumber_TabInvoice.Visible = false; ;

                // reset validation provider
                resetValidationProvider(dxValidationProvider10);

                // set focus
                LU_InvoiceNumber_TabInvoice.Focus();
            }
            else
            {
                // set buttons
                BTN_New_TabInvoice.Visible      = false;
                BTN_Update_TabInvoice.Enabled   = false;
                BTN_Delete_TabInvoice.Enabled   = false;
                BTN_Submit_TabInvoice.Visible   = true;
                BTN_Cancel_TabInvoice.Visible   = true;

                // set input editors
                LU_InvoiceNumber_TabInvoice.Visible = false;
                TE_InvoiceNumber_TabInvoice.Visible = true; ;

                // set focus
                TE_InvoiceNumber_TabInvoice.Focus();
            }
        }

        private void deleteInvoice(Model.Invoice invoiceToDelete)
        {
            // delete this invoice
            invoiceToDelete.Enable = false;
            s_InvoiceMgr.Update(invoiceToDelete);

            // delete payments related to this invoice
            List<Model.Payment> payments = s_PaymentMgr.GetModelList("InvoiceID=" + invoiceToDelete.id);
            for (int i = 0; i < payments.Count; i++)
            {
                s_PaymentMgr.Delete(payments[i].id);
            }
        }

        private void showMsg_TabInvoice(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success_TabInvoice.ForeColor = Color.Green;
            }
            else
            {
                LB_Success_TabInvoice.ForeColor = Color.Red;
            }

            LB_Success_TabInvoice.Text = msg;
            LB_Success_TabInvoice.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success_TabInvoice.Size.Width / 2),
                                                       LB_Success_TabInvoice.Location.Y);
        }

        private void getLastInvoiceNumber(char fifthNumber, out String lastInvoiceNumber, out DateTime lastInvoiceDate)
        {
            lastInvoiceNumber   = null;
            lastInvoiceDate     = DateTime.Now;

            DataSet ds = s_InvoiceMgr.GetInvoiceNumber("Enable=1");
            int rowsCount = ds.Tables[0].Rows.Count;
            for (int n = 0; n < rowsCount; n++)
            {
                String invoiceNumber = ds.Tables[0].Rows[n]["InvoiceNumber"].ToString();
                DateTime invoiceDate = DateTime.Parse(ds.Tables[0].Rows[n]["InvoiceDate"].ToString());
                
                // check fifth number
                if (invoiceNumber.Length >= 5 && 
                    invoiceNumber[4] == fifthNumber)
                {
                    if (lastInvoiceNumber == null)
                    {
                        lastInvoiceNumber   = invoiceNumber;
                        lastInvoiceDate     = invoiceDate;
                    }
                    else
                    {
                        try
                        {
                            int nInvoiceNumber      = Int32.Parse(invoiceNumber);
                            int nLastInvoiceNumber  = Int32.Parse(lastInvoiceNumber);
                            if (nInvoiceNumber > nLastInvoiceNumber)
                            {
                                lastInvoiceNumber   = invoiceNumber;
                                lastInvoiceDate     = invoiceDate;
                            }
                        }
                        catch (System.Exception)
                        {
                        	// do nothing
                        }
                    }
                }
            }
        }

        private void showLastInvoiceNumber(String lastInvoiceNumber, DateTime lastInvoiceDate)
        {
            if (String.IsNullOrEmpty(lastInvoiceNumber))
            {
                LB_LastInvoiceNumber_TabInvoice.ForeColor   = Color.Red;
                LB_LastInvoiceNumber_TabInvoice.Text        = "No Invoice Number Found!";
                LB_LastInvoiceNumber_TabInvoice.Location    = new Point((xtraTabControl1.Size.Width / 2 - LB_LastInvoiceNumber_TabInvoice.Size.Width / 2),
                                                                        LB_LastInvoiceNumber_TabInvoice.Location.Y);
            
                LB_LastInvoiceDate_TabInvoice.Text          = "";
            }
            else
            {
                LB_LastInvoiceNumber_TabInvoice.ForeColor   = Color.Green;
                LB_LastInvoiceNumber_TabInvoice.Text        = "Last Invoice Number at " + DateTime.Now.ToLongTimeString() + ": [" + lastInvoiceNumber + "] ";
                LB_LastInvoiceNumber_TabInvoice.Location    = new Point((xtraTabControl1.Size.Width / 2 - LB_LastInvoiceNumber_TabInvoice.Size.Width / 2),
                                                                        LB_LastInvoiceNumber_TabInvoice.Location.Y);
                LB_LastInvoiceDate_TabInvoice.ForeColor     = Color.Green;
                LB_LastInvoiceDate_TabInvoice.Text          = "Last Invoice Date: [" + lastInvoiceDate.ToShortDateString() + "] ";
                LB_LastInvoiceDate_TabInvoice.Location      = new Point(LB_LastInvoiceNumber_TabInvoice.Location.X,
                                                                        LB_LastInvoiceDate_TabInvoice.Location.Y);
            }
        }
        #endregion

        #region Members
        private bool m_firstLoad_TabInvoice             = true;
        private Model.Invoice m_currentInvoice          = null;
        private DataSet m_PatientList_TabInvoice        = null;
        private DataSet m_InvoiceList_TabInvoice        = null;
        // this is added to resolve the strange change of patient name 
        // when updating invoice data without changing the patient name
        private bool m_patientNameChanged_TabInvoice    = false;
        #endregion
        #endregion

        #region TabReports
        #region EventHandlers
        private void LU_ServiceType_TabReports_EditValueChanged(object sender, EventArgs e)
        {
            clearLookUpEdit(LU_Staff_TabReports);

            // refresh data
            refreshData_TabReports(false, false, true, false, false);
        }

        private void BTN_Show_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider9.Validate())
            {
                showMsg_TabReports(false, "Date Info Incomplete!");
                return;
            }

            // get conditions
            List<bool> byConditions = new List<bool>();
            byConditions.Add(CE_ByCompany_TabReports.Checked);
            byConditions.Add(CE_ByService_TabReports.Checked);
            byConditions.Add(CE_ByStaff_TabReports.Checked);
            byConditions.Add(CE_ByReferral_TabReports.Checked);

            List<String> reportValues = new List<String>();
            // company id value
            if (LU_Company_TabReports.EditValue != null)
            {
                reportValues.Add(LU_Company_TabReports.EditValue.ToString());
            }
            else
            {
                reportValues.Add(null);
            }

            // service id value
            if (LU_ServiceType_TabReports.EditValue != null)
            {
                reportValues.Add(LU_ServiceType_TabReports.EditValue.ToString());
            }
            else
            {
                reportValues.Add(null);
            }

            // staff id value
            if (LU_Staff_TabReports.EditValue != null)
            {
                reportValues.Add(LU_Staff_TabReports.EditValue.ToString());
            }
            else
            {
                reportValues.Add(null);
            }

            // referral value
            if (LU_Referer_TabReports.EditValue != null)
            {
                reportValues.Add(LU_Referer_TabReports.Text);
            }
            else
            {
                reportValues.Add(null);
            }

            // check if report values are OK
            bool reportValuesOK = true;
            for (int i = 0; i < byConditions.Count; i++)
            {
                if (byConditions[i] && reportValues[i] == null)
                {
                    reportValuesOK = false;
                    break;
                }
            }

            // show report
            if (!reportValuesOK)
            {
                showMsg_TabReports(false, "Report Info Incomplete!");
                return;
            }
            else
            {
                showMsg_TabReports(true, "Generating Report...");
                showReport(reportValues, 
                           byConditions,
                           DE_From_TabReports.DateTime,
                           DE_To_TabReports.DateTime);
                showMsg_TabReports(true, "Report Generated!");
            }
        }


        private void BTN_ShowUnpaid_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider17.Validate())
            {
                showMsg_TabReports(false, "Info Incomplete!");
                return;
            }

            // get company id
            int nCompanyID = Int32.Parse(LU_Company_TabReports.EditValue.ToString());

            // show report
            showMsg_TabReports(true, "Generating Report...");
            showUnpaidReport(nCompanyID, 
                             DE_From_TabReports.DateTime, 
                             DE_To_TabReports.DateTime);
            showMsg_TabReports(true, "Report Generated!");
        }

        private void BTN_General_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider17.Validate())
            {
                showMsg_TabReports(false, "Info Incomplete!");
                return;
            }

            // get company id
            int nCompanyID = Int32.Parse(LU_Company_TabReports.EditValue.ToString());

            // show report
            showMsg_TabReports(true, "Generating Report...");
            showGeneralReport(nCompanyID,
                              DE_From_TabReports.DateTime,
                              DE_To_TabReports.DateTime);
            showMsg_TabReports(true, "Report Generated!");
        }

        private void BTN_Show2_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider13.Validate())
            {
                showMsg2_TabReports(false, "Consultation Info Incomplete!");
                return;
            }

            // check rate value
            double rate = 0;
            try
            {
                rate = Double.Parse(TE_ServiceFee_TabReports.Text);
                if (rate < 0)
                {
                    showMsg2_TabReports(false, "Service Fee Rate Invalid!");
                    return;
                }
            }
            catch (System.Exception)
            {
                showMsg2_TabReports(false, "Service Fee Rate Invalid!");
                return;
            }

            // show report
            showMsg2_TabReports(true, "Generating Report...");
            showReport2(LU_Referer2_TabReports.Text,
                        rate,
                        DE_From2_TabReports.DateTime, 
                        DE_To2_TabReports.DateTime);
            showMsg2_TabReports(true, "Report Generated!");
        }

        private void BTN_Show3_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider14.Validate())
            {
                showMsg3_TabReports(false, "Date Info or Patient Info Incomplete!");
                return;
            }

            // sort by
            int sortBy          = Int32.Parse(RG_SortBy_TabReports.EditValue.ToString());

             // patient id
            int patientID       = Int32.Parse(LU_Patient_TabReports.EditValue.ToString());

             // patient name
            String patientName  = LU_Patient_TabReports.Text;

            // show report
            showMsg3_TabReports(true, "Generating Report...");
            showReport3(sortBy, 
                        patientID, 
                        patientName,
                        DE_From3_TabReports.DateTime, 
                        DE_To3_TabReports.DateTime);
            showMsg3_TabReports(true, "Report Generated!");
        }

        private void BTN_ShowAttendedCE_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider16.Validate())
            {
                showMsg4_TabReports(false, "Info Incomplete!");
                return;
            }

            // get year
            int nYear = DE_CEYear_TabReports.DateTime.Year;

            // create date time
            DateTime from   = new DateTime(nYear, 1, 1);
            DateTime to     = new DateTime(nYear + 1, 1, 1).AddDays(-1);

            // show report
            showMsg4_TabReports(true, "Generating Report...");
            showReport4(from, to, true);  
            showMsg4_TabReports(true, "Report Generated!");
        }

        private void BTN_ShowNotAttendedCE_TabReports_Click(object sender, EventArgs e)
        {
            // check validity
            if (!dxValidationProvider16.Validate())
            {
                showMsg4_TabReports(false, "Info Incomplete!");
                return;
            }

            // get year
            int nYear = DE_CEYear_TabReports.DateTime.Year;

            // create date time
            DateTime from   = new DateTime(nYear, 1, 1);
            DateTime to     = new DateTime(nYear + 1, 1, 1).AddDays(-1);

            // show report
            showMsg4_TabReports(true, "Generating Report...");
            showReport4(from, to, false);
            showMsg4_TabReports(true, "Report Generated!");
        }
        #endregion

        #region Functions
        // show authorization report
        private void showReport(List<String> reportValues, 
                                List<bool> byConditions, 
                                DateTime dtFrom, 
                                DateTime dtTo)
        {
            String from = dtFrom.ToString("yyyy-MM-dd 00:00:00");
            String to   = dtTo.ToString("yyyy-MM-dd 23:59:59");

            // create where string
            String strWhere = "";
            for (int i = 0; i < byConditions.Count; i++)
            {
                if (!byConditions[i])
                {
                    continue;
                }

                int reportType = i;
                String reportValue = reportValues[i];
                switch (reportType)
                {
                    case 0:
                        // list all
                        if (reportValue == "0")
                        {
                            // all companies, no constraint
                        }
                        else
                        {
                            strWhere += "CompanyID = " + reportValue + " AND ";
                        }
                        break;
                    case 1:
                        strWhere += "ServiceID = " + reportValue + " AND ";
                        break;
                    case 2:
                        strWhere += "StaffID = " + reportValue + " AND ";
                        break;
                    case 3:
                        strWhere += "Referer='" + reportValue +
                            "' AND (Service='PCA' OR Service='PCW' OR Service='HHA') AND ";
                        break;
                }
            }
            strWhere += "ServiceEnd >= '" + from + "' AND ServiceStart <= '" + to + "' ORDER BY PatientID";

            // get dateset
            DataSet ds = s_ReportViewMgr.GetList2(strWhere);

            // output ds
            // create report
            XRFullReport report = new XRFullReport(ds);
            report.ShowPreview();
        }

        // show consultation report
        private void showReport2(String referer, 
                                 double rate, 
                                 DateTime dtServiceFrom, 
                                 DateTime dtServiceTo)
        {
            // Invoice Date = Service Date + 1
            DateTime dtInvoiceFrom  = dtServiceFrom.AddDays(1);
            DateTime dtInvoiceTo    = dtServiceTo.AddDays(1); 
            String from             = dtInvoiceFrom.ToString("yyyy-MM-dd 00:00:00");
            String to               = dtInvoiceTo.ToString("yyyy-MM-dd 23:59:59");

            DataSet ds = s_ConsultationFeeViewMgr.GetList("Referer='" + referer +
                                                          "' AND Enable=1" + 
                                                          "  AND InvoiceDate >= '" + from +
                                                          "' AND InvoiceDate <= '" + to +
                                                          "' ORDER BY PatientID");

            int rowsCount = ds.Tables[0].Rows.Count;
            for (int n = 0; n < rowsCount; n++)
            {
                // only HHA invoices are calculated here
                if (!isHHAInvoice(Int32.Parse(ds.Tables[0].Rows[n]["InvoiceID"].ToString())))
                {
                    // mark for later deletion
                    ds.Tables[0].Rows[n].Delete();
                    continue;
                }

                // calculate service hours (amount billed / unit rate) and save to amount field
                double serviceHours = 0;
                try
                {
                    double amountBilled = Double.Parse(ds.Tables[0].Rows[n]["Amount"].ToString());
                    double unitRate     = Double.Parse(ds.Tables[0].Rows[n]["UnitRate"].ToString());
                    serviceHours        = amountBilled / unitRate;
                }
                catch (System.Exception)
                {
                    serviceHours = 0;
                }
                ds.Tables[0].Rows[n]["Amount"] = serviceHours.ToString("0.00");

                // save patient name in lastname field
                String lastName     = ds.Tables[0].Rows[n]["LastName"].ToString();
                String firstName    = ds.Tables[0].Rows[n]["FirstName"].ToString();
                ds.Tables[0].Rows[n]["LastName"] = lastName + "," + firstName;

                // save service fee rate in firstname field
                ds.Tables[0].Rows[n]["FirstName"] = rate.ToString("0.00");

                // save total (service hours * service fee rate) in unitrate field
                double total = serviceHours * rate;
                ds.Tables[0].Rows[n]["UnitRate"] = total.ToString("0.00");
            }
            //ds.WriteXmlSchema(@"C:/1.xsd");

            // accept deletion changes
            ds.Tables[0].AcceptChanges();

            // output ds
            // create report
            XRConsultationReport report = new XRConsultationReport(ds);
            report.setInfo(dtServiceFrom, dtServiceTo, referer);
            report.ShowPreview();
        }

        // show invoice payment report
        // we should change it, when we have extended "InvoicePaymentView"
        private void showReport3(int sortBy, 
                                 int patientID, 
                                 String patientName, 
                                 DateTime dtInvoiceFrom, 
                                 DateTime dtInvoiceTo)
        {
            String from = dtInvoiceFrom.ToString("yyyy-MM-dd 00:00:00");
            String to   = dtInvoiceTo.ToString("yyyy-MM-dd 23:59:59");

            // limit with patient id
            String sPatientID = null;
            if (patientID > 0)
            {
                sPatientID = " AND i.PatientID=" + patientID.ToString();
            }
            else
            {
                // list all patients
                sPatientID = "";
            }

            DataSet ds = null;
            switch (sortBy)
            {
                case 0:
                    // We use GetList2 here, which joins view "InvoicePaymentView" and 
                    // table "Invoice" when selecting data. It's only a silly solution.
                    // In fact, we should extend "InvoicePaymentView" and use only GetList 
                    // which does not need table "Invoice". However, we don't want 
                    // to change the database at the moment.
                    ds = s_InvoicePaymentViewMgr.GetList2("v.Enable=1" + sPatientID + 
                                                         "  AND v.InvoiceDate >= '" + from +
                                                         "' AND v.InvoiceDate <= '" + to +
                                                         "' ORDER BY v.InvoiceDate");
                    break;
                case 1:
                    ds = s_InvoicePaymentViewMgr.GetList2("v.Enable=1" + sPatientID +
                                                         "  AND v.InvoiceDate >= '" + from +
                                                         "' AND v.InvoiceDate <= '" + to +
                                                         "' ORDER BY v.InvoiceNumber");
                    break;
                case 2:
                    ds = s_InvoicePaymentViewMgr.GetList2("v.Enable=1" + sPatientID +
                                                         "  AND v.InvoiceDate >= '" + from +
                                                         "' AND v.InvoiceDate <= '" + to +
                                                         "' ORDER BY i.PatientID");
                    break;
            }
            ds.Tables[0].Columns.Add("Balance");

            int rowsCount = ds.Tables[0].Rows.Count;
            for (int n = 0; n < rowsCount; n++)
            {
                // if null or empty, $0 is received
                String receivedStr = ds.Tables[0].Rows[n]["Received"].ToString();
                if (String.IsNullOrEmpty(receivedStr))
                {
                    ds.Tables[0].Rows[n]["Received"] = "0";
                }

                double balance = 0;
                try
                {
                    double amountBilled = Double.Parse(ds.Tables[0].Rows[n]["Amount"].ToString());
                    double received     = Double.Parse(ds.Tables[0].Rows[n]["Received"].ToString());
                    balance             = amountBilled - received;
                }
                catch (System.Exception)
                {
                	balance             = -1;
                }
                ds.Tables[0].Rows[n]["Balance"] = balance.ToString("0.00");
            }
            //ds.WriteXmlSchema(@"C:/1.xsd");

            // output ds
            // create report
            XRInvoicePaymentReport report = new XRInvoicePaymentReport(ds);
            report.setInfo(dtInvoiceFrom, dtInvoiceTo, patientName);
            report.ShowPreview();
        }

        // continue education report
        private void showReport4(DateTime dtFrom, DateTime dtTo, bool bAttend)
        {
            String from = dtFrom.ToString("yyyy-MM-dd 00:00:00");
            String to   = dtTo.ToString("yyyy-MM-dd 23:59:59");

            List<Model.ContinueEducationRecord> allCERecords 
                = s_CERecordMgr.GetModelList("EducationStart >= '" + from + "' AND EducationEnd <= '" + to + "'");
            
            Hashtable attendedStaff = new Hashtable();
            for (int i = 0; i < allCERecords.Count; i++)
            {
                String sid = allCERecords[i].StaffID.ToString();
                if (!attendedStaff.Contains(sid))
                {
                    attendedStaff.Add(sid, null);
                }
            }

            // get service id and service name mapping
            Hashtable serviceNames = s_ServiceMgr.GetIdNameMapping();

            // create satisfy list
            DataSet ds = s_StaffMgr.GetList("Enable=1 AND Waiting=0 ORDER BY ServiceID, Name");       
            int rowsCount = ds.Tables[0].Rows.Count;
            for (int i = 0; i < rowsCount; i++)
            {
                // put service name in fax field
                String serviceId = ds.Tables[0].Rows[i]["ServiceID"].ToString();
                ds.Tables[0].Rows[i]["Fax"] = serviceNames[serviceId];

                // delete items
                String sid = ds.Tables[0].Rows[i]["id"].ToString();
                bool hasAttended = attendedStaff.Contains(sid);
                if ((bAttend && !hasAttended) || (!bAttend && hasAttended))
                {
                    ds.Tables[0].Rows[i].Delete();
                }
            }
            ds.Tables[0].AcceptChanges();

            //ds.WriteXmlSchema(@"C:/1.xsd");

            // output ds
            // create report
            XRContinueEducation report = new XRContinueEducation(ds);
            report.setInfo(dtFrom, dtTo, bAttend);
            report.ShowPreview();
        }

        // show Unpaid report
        private void showUnpaidReport(int nCompany, DateTime dtFrom, DateTime dtTo)
        {
            String from = dtFrom.ToString("yyyy-MM-dd 00:00:00");
            String to   = dtTo.ToString("yyyy-MM-dd 23:59:59");

            String company = "All Companies";

            // create where string
            String strWhere = "";
            if (nCompany > 0)
            {
                strWhere += "CompanyID = " + nCompany + " AND ";

                // get company name
                Hashtable nameMap = s_CompanyMgr.GetIdNameMapping();
                company = nameMap[nCompany.ToString()].ToString();
            }
            strWhere += "Enable=1 AND InvoiceDate >= '" + from + "' AND InvoiceDate <= '" + to + "' ORDER BY CompanyID, InvoiceNumber, ReceivedDate";

            
            // get dateset
            DataSet ds = s_InvoicePaymentViewMgr2.GetListWithBalance1(strWhere);

            //ds.WriteXmlSchema(@"C:/1.xsd");

            // output ds
            // create report
            XRUnpaidReport report = new XRUnpaidReport(ds);
            report.setInfo(dtFrom, dtTo, company);
            report.ShowPreview();
        }

        // show General report
        private void showGeneralReport(int nCompany, DateTime dtFrom, DateTime dtTo)
        {
            String from = dtFrom.ToString("yyyy-MM-dd 00:00:00");
            String to   = dtTo.ToString("yyyy-MM-dd 23:59:59");

            String company = "All Companies";

            // create where string
            String strWhere = "";
            if (nCompany > 0)
            {
                strWhere += "CompanyID = " + nCompany + " AND ";

                // get company name
                Hashtable nameMap = s_CompanyMgr.GetIdNameMapping();
                company = nameMap[nCompany.ToString()].ToString();
            }
            strWhere += "Enable=1 AND InvoiceDate >= '" + from + "' AND InvoiceDate <= '" + to + "' ORDER BY CompanyID, InvoiceNumber, ReceivedDate";


            // get dateset
            DataSet ds = s_InvoicePaymentViewMgr2.GetListWithBalance2(strWhere);

            //ds.WriteXmlSchema(@"C:/1.xsd");

            // output ds
            // create report
            XRGeneralReport report = new XRGeneralReport(ds);
            report.setInfo(dtFrom, dtTo, company);
            report.ShowPreview();
        }

        // refresh data from database
        private void refreshData_TabReports(bool bCompanyList,
                                            bool bServiceList,
                                            bool bStaffList,
                                            bool bRefererList,
                                            bool bPatientList)
        {
            // refresh company list
            if (bCompanyList)
            {
                m_CompanyList_TabReports = s_CompanyMgr.GetList("Enable=1");

                // bind company names
                if (m_CompanyList_TabReports != null)
                {
                    // add "All" to company list
                    DataRow row = m_CompanyList_TabReports.Tables[0].NewRow();
                    row["id"]       = 0;
                    row["Company"]  = "All";
                    m_CompanyList_TabReports.Tables[0].Rows.InsertAt(row, 0);

                    // bind DataSource
                    LU_Company_TabReports.Properties.DataSource     = m_CompanyList_TabReports.Tables[0];
                    LU_Company_TabReports.Properties.DisplayMember  = "Company";
                    LU_Company_TabReports.Properties.ValueMember    = "id";

                    // set default to "All"
                    LU_Company_TabReports.EditValue = 0;
                }
            }

            // refresh service list
            if (bServiceList)
            {
                m_ServceList_TabReports = s_ServiceMgr.GetList("Enable=1");

                // bind service names
                if (m_ServceList_TabReports != null)
                {
                    // bind DataSource
                    LU_ServiceType_TabReports.Properties.DataSource     = m_ServceList_TabReports.Tables[0];
                    LU_ServiceType_TabReports.Properties.DisplayMember  = "Service";
                    LU_ServiceType_TabReports.Properties.ValueMember    = "id";
                }
            }

            // refresh staff list
            if (bStaffList)
            {
                if (LU_ServiceType_TabReports.EditValue != null)
                {
                    // get staff list
                    String sid = LU_ServiceType_TabReports.EditValue.ToString();
                    if (!String.IsNullOrEmpty(sid))
                    {
                        m_StaffList_TabReports = s_StaffMgr.GetList("ServiceID=" + sid + " AND Enable=1 ORDER BY Name");
                    }
                    else
                    {
                        m_StaffList_TabReports = s_StaffMgr.GetList("Enable=1 ORDER BY Name");
                    }
                }
                else
                {
                    m_StaffList_TabReports = s_StaffMgr.GetList("Enable=1 ORDER BY Name");
                }

                // bind staff names
                if (m_StaffList_TabReports != null)
                {
                    // bind DataSource
                    LU_Staff_TabReports.Properties.DataSource       = m_StaffList_TabReports.Tables[0];
                    LU_Staff_TabReports.Properties.DisplayMember    = "Name";
                    LU_Staff_TabReports.Properties.ValueMember      = "id";
                }
            }

            // refresh referer list
            if (bRefererList)
            {
                m_RefererList_TabReports = s_PatientMgr.GetReferers("");

                // bind referer names
                if (m_RefererList_TabReports != null)
                {
                    // bind DataSource
                    LU_Referer_TabReports.Properties.DataSource     = m_RefererList_TabReports.Tables[0];
                    LU_Referer_TabReports.Properties.DisplayMember  = "Referer";
                    LU_Referer_TabReports.Properties.ValueMember    = "RefererPhone";

                    // bind DataSource
                    LU_Referer2_TabReports.Properties.DataSource    = m_RefererList_TabReports.Tables[0];
                    LU_Referer2_TabReports.Properties.DisplayMember = "Referer";
                    LU_Referer2_TabReports.Properties.ValueMember   = "RefererPhone";
                }
            }

            // refresh patient list
            if (bPatientList)
            {
                // GetNames ORDER BY LastName in default
                m_PatientList_TabReports = s_PatientMgr.GetNames("Enable=1");

                // bind patient names
                if (m_PatientList_TabReports != null)
                {
                    // add "All" to patient list
                    DataRow row     = m_PatientList_TabReports.Tables[0].NewRow();
                    row["id"]       = 0;
                    row["LastName"] = "All";
                    m_PatientList_TabReports.Tables[0].Rows.InsertAt(row, 0);

                    // bind DataSource
                    LU_Patient_TabReports.Properties.DataSource       = m_PatientList_TabReports.Tables[0];
                    LU_Patient_TabReports.Properties.DisplayMember    = "LastName";
                    LU_Patient_TabReports.Properties.ValueMember      = "id";

                    // set default to "All"
                    LU_Patient_TabReports.EditValue = 0;
                }
            }
        }

        private void clearControls_TabReports()
        {
            // authorization reports
            // lookup edits
            clearLookUpEdit(LU_Company_TabReports);
            clearLookUpEdit(LU_ServiceType_TabReports);
            clearLookUpEdit(LU_Referer_TabReports);
            clearLookUpEdit(LU_Staff_TabReports);

            // textboxes
            DE_From_TabReports.DateTime         = DateTime.Now;
            DE_To_TabReports.DateTime           = DateTime.Now;

            // consultation fee
            // lookup edits
            clearLookUpEdit(LU_Referer2_TabReports);

            // textboxes
            TE_ServiceFee_TabReports.Text       = "";
            DE_From2_TabReports.DateTime        = DateTime.Now;
            DE_To2_TabReports.DateTime          = DateTime.Now;

            // payment claimed and received
            // lookup edits
            clearLookUpEdit(LU_Patient_TabReports);

            // textboxes
            DE_From3_TabReports.DateTime        = DateTime.Now;
            DE_To3_TabReports.DateTime          = DateTime.Now;
        }

        private void showMsg_TabReports(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success_TabReports.ForeColor = Color.Green;
            }
            else
            {
                LB_Success_TabReports.ForeColor = Color.Red;
            }

            LB_Success_TabReports.Text = msg;
            LB_Success_TabReports.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success_TabReports.Size.Width / 2),
                                                        LB_Success_TabReports.Location.Y);
        }

        private void showMsg2_TabReports(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success2_TabReports.ForeColor = Color.Green;
            }
            else
            {
                LB_Success2_TabReports.ForeColor = Color.Red;
            }

            LB_Success2_TabReports.Text = msg;
            LB_Success2_TabReports.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success2_TabReports.Size.Width / 2),
                                                        LB_Success2_TabReports.Location.Y);
        }

        private void showMsg3_TabReports(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success3_TabReports.ForeColor = Color.Green;
            }
            else
            {
                LB_Success3_TabReports.ForeColor = Color.Red;
            }

            LB_Success3_TabReports.Text = msg;
            LB_Success3_TabReports.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success3_TabReports.Size.Width / 2),
                                                        LB_Success3_TabReports.Location.Y);
        }

        private void showMsg4_TabReports(bool bSuccess, String msg)
        {
            if (bSuccess)
            {
                LB_Success4_TabReports.ForeColor = Color.Green;
            }
            else
            {
                LB_Success4_TabReports.ForeColor = Color.Red;
            }

            LB_Success4_TabReports.Text = msg;
            LB_Success4_TabReports.Location = new Point((xtraTabControl1.Size.Width / 2 - LB_Success4_TabReports.Size.Width / 2),
                                                        LB_Success4_TabReports.Location.Y);
        }

        private bool isHHAInvoice(int invoiceID)
        {
            // the fifth digit of invoice number for HHA is 0
            Model.Invoice invoice = s_InvoiceMgr.GetModel(invoiceID);
            if (invoice != null)
            {
                return (invoice.InvoiceNumber.Length >= 5 &&
                        invoice.InvoiceNumber[4] == '0');
            } 
            else
            {
                return false;
            }
        }
        #endregion

        #region Members
        private bool m_firstLoad_TabReports         = true;
        private DataSet m_CompanyList_TabReports    = null;
        private DataSet m_ServceList_TabReports     = null;
        private DataSet m_StaffList_TabReports      = null;
        private DataSet m_RefererList_TabReports    = null;
        private DataSet m_PatientList_TabReports    = null;
        #endregion

        #endregion

        private static BLL.AuthorizationRecord s_AuthRecordMgr          = new BLL.AuthorizationRecord();
        private static BLL.AuthorizationRecordView s_AuthRecordViewMgr  = new BLL.AuthorizationRecordView();
        private static BLL.ConsultationFeeView s_ConsultationFeeViewMgr = new BLL.ConsultationFeeView();
        private static BLL.InvoicePaymentView s_InvoicePaymentViewMgr   = new BLL.InvoicePaymentView();
        private static BLL.InvoicePaymentView2 s_InvoicePaymentViewMgr2   = new BLL.InvoicePaymentView2();
        private static BLL.ContinueEducationRecord s_CERecordMgr        = new BLL.ContinueEducationRecord();
        private static BLL.Company s_CompanyMgr         = new BLL.Company();
        private static BLL.Patient s_PatientMgr         = new BLL.Patient();
        private static BLL.ReportView s_ReportViewMgr   = new BLL.ReportView();
        private static BLL.Service s_ServiceMgr         = new BLL.Service();
        private static BLL.Staff s_StaffMgr             = new BLL.Staff();
        private static BLL.Invoice s_InvoiceMgr         = new BLL.Invoice();
        private static BLL.Payment s_PaymentMgr         = new BLL.Payment();
    }
}